]> err.no Git - linux-2.6/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
authorLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 15:16:37 +0000 (08:16 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 15:16:37 +0000 (08:16 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (25 commits)
  [POWERPC] Add support for the mpc832x mds board
  [POWERPC] Add initial support for the e300c2 core
  [POWERPC] Add MPC8360EMDS default dts file
  [POWERPC] Add MPC8360EMDS board support
  [POWERPC] Add QUICC Engine (QE) infrastructure
  [POWERPC] Add QE device tree node definition
  [POWERPC] Don't try to just continue if xmon has no input device
  [POWERPC] Fix a printk in pseries_mpic_init_IRQ
  [POWERPC] Get default baud rate in udbg_scc
  [POWERPC] Fix zImage.coff on oldworld PowerMac
  [POWERPC] Fix xmon=off and cleanup xmon initialisation
  [POWERPC] Cleanup include/asm-powerpc/xmon.h
  [POWERPC] Update swim3 printk after blkdev.h change
  [POWERPC] Cell interrupt rework
  POWERPC: mpc82xx merge: board-specific/platform stuff(resend)
  POWERPC: 8272ads merge to powerpc: common stuff
  POWERPC: Added devicetree for mpc8272ads board
  [POWERPC] iSeries has no legacy I/O
  [POWERPC] implement BEGIN/END_FW_FTR_SECTION
  [POWERPC] iSeries does not need pcibios_fixup_resources
  ...

867 files changed:
CREDITS
Documentation/DMA-mapping.txt
Documentation/DocBook/kernel-api.tmpl
Documentation/DocBook/libata.tmpl
Documentation/DocBook/usb.tmpl
Documentation/DocBook/writing_usb_driver.tmpl
Documentation/IPMI.txt
Documentation/MSI-HOWTO.txt
Documentation/RCU/checklist.txt
Documentation/RCU/rcu.txt
Documentation/RCU/torture.txt
Documentation/RCU/whatisRCU.txt
Documentation/aoe/todo.txt
Documentation/arm/SA1100/serial_UART
Documentation/arm/Samsung-S3C24XX/EB2410ITX.txt
Documentation/arm/Samsung-S3C24XX/GPIO.txt
Documentation/arm/Samsung-S3C24XX/Overview.txt
Documentation/arm/Samsung-S3C24XX/S3C2412.txt
Documentation/block/as-iosched.txt
Documentation/block/barrier.txt
Documentation/block/biodoc.txt
Documentation/block/deadline-iosched.txt
Documentation/cciss.txt
Documentation/computone.txt
Documentation/cpu-freq/cpufreq-stats.txt
Documentation/cpu-freq/governors.txt
Documentation/cputopology.txt
Documentation/dell_rbu.txt
Documentation/devices.txt
Documentation/driver-model/class.txt
Documentation/driver-model/driver.txt
Documentation/driver-model/overview.txt
Documentation/dvb/avermedia.txt
Documentation/dvb/cards.txt
Documentation/dvb/ci.txt
Documentation/dvb/faq.txt
Documentation/ecryptfs.txt [new file with mode: 0644]
Documentation/eisa.txt
Documentation/exception.txt
Documentation/fb/fbcon.txt
Documentation/fb/sisfb.txt
Documentation/fb/sstfb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/00-INDEX
Documentation/filesystems/befs.txt
Documentation/filesystems/configfs/configfs.txt
Documentation/filesystems/directory-locking
Documentation/filesystems/dlmfs.txt
Documentation/filesystems/ext2.txt
Documentation/filesystems/files.txt
Documentation/filesystems/ntfs.txt
Documentation/filesystems/proc.txt
Documentation/filesystems/spufs.txt
Documentation/filesystems/sysfs.txt
Documentation/filesystems/tmpfs.txt
Documentation/filesystems/vfat.txt
Documentation/filesystems/vfs.txt
Documentation/fujitsu/frv/mmu-layout.txt
Documentation/highuid.txt
Documentation/hrtimers.txt
Documentation/ia64/efirtc.txt
Documentation/ia64/fsys.txt
Documentation/ia64/mca.txt
Documentation/ibm-acpi.txt
Documentation/ide.txt
Documentation/input/amijoy.txt
Documentation/input/atarikbd.txt
Documentation/input/cs461x.txt
Documentation/input/ff.txt
Documentation/input/gameport-programming.txt
Documentation/input/input.txt
Documentation/input/joystick-parport.txt
Documentation/input/joystick.txt
Documentation/input/yealink.txt
Documentation/ioctl/hdio.txt
Documentation/isdn/INTERFACE.fax
Documentation/isdn/README.hysdn
Documentation/java.txt
Documentation/kbuild/kconfig-language.txt
Documentation/kbuild/makefiles.txt
Documentation/kdump/kdump.txt
Documentation/kernel-docs.txt
Documentation/kernel-parameters.txt
Documentation/keys.txt
Documentation/kobject.txt
Documentation/laptop-mode.txt
Documentation/lockdep-design.txt
Documentation/m68k/kernel-options.txt
Documentation/mca.txt
Documentation/md.txt
Documentation/memory-barriers.txt
Documentation/mono.txt
Documentation/networking/3c509.txt
Documentation/networking/NAPI_HOWTO.txt
Documentation/networking/arcnet-hardware.txt
Documentation/networking/bonding.txt
Documentation/networking/cs89x0.txt
Documentation/networking/cxgb.txt
Documentation/networking/decnet.txt
Documentation/networking/dl2k.txt
Documentation/networking/dmfe.txt
Documentation/networking/driver.txt
Documentation/networking/e1000.txt
Documentation/networking/fib_trie.txt
Documentation/networking/gen_stats.txt
Documentation/networking/ip-sysctl.txt
Documentation/networking/netconsole.txt
Documentation/networking/netif-msg.txt
Documentation/networking/operstates.txt
Documentation/networking/packet_mmap.txt
Documentation/networking/pktgen.txt
Documentation/networking/s2io.txt
Documentation/networking/sk98lin.txt
Documentation/networking/skfp.txt
Documentation/networking/slicecom.txt
Documentation/networking/smctr.txt
Documentation/networking/tcp.txt
Documentation/networking/tms380tr.txt
Documentation/networking/vortex.txt
Documentation/networking/wan-router.txt
Documentation/nfsroot.txt
Documentation/pci-error-recovery.txt
Documentation/pi-futex.txt
Documentation/pm.txt
Documentation/pnp.txt
Documentation/power/pci.txt
Documentation/power/swsusp.txt
Documentation/power/tricks.txt
Documentation/power/userland-swsusp.txt
Documentation/power/video.txt
Documentation/powerpc/booting-without-of.txt
Documentation/powerpc/eeh-pci-error-recovery.txt
Documentation/powerpc/hvcs.txt
Documentation/prio_tree.txt
Documentation/rocket.txt
Documentation/rpc-cache.txt
Documentation/s390/3270.txt
Documentation/s390/Debugging390.txt
Documentation/s390/cds.txt
Documentation/s390/crypto/crypto-API.txt
Documentation/s390/driver-model.txt
Documentation/s390/monreader.txt
Documentation/s390/s390dbf.txt
Documentation/sched-coding.txt
Documentation/sched-design.txt
Documentation/scsi/ChangeLog.1992-1997
Documentation/scsi/NinjaSCSI.txt
Documentation/scsi/aacraid.txt
Documentation/scsi/aic79xx.txt
Documentation/scsi/aic7xxx.txt
Documentation/scsi/aic7xxx_old.txt
Documentation/scsi/dc395x.txt
Documentation/scsi/dpti.txt
Documentation/scsi/ibmmca.txt
Documentation/scsi/megaraid.txt
Documentation/scsi/ncr53c8xx.txt
Documentation/scsi/osst.txt
Documentation/scsi/ppa.txt
Documentation/scsi/scsi-changer.txt
Documentation/scsi/scsi_eh.txt
Documentation/scsi/st.txt
Documentation/scsi/sym53c8xx_2.txt
Documentation/scsi/tmscsim.txt
Documentation/sh/kgdb.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/Audiophile-Usb.txt
Documentation/sound/alsa/CMIPCI.txt
Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
Documentation/sound/alsa/MIXART.txt
Documentation/sound/alsa/Procfile.txt
Documentation/sound/oss/AWE32 [deleted file]
Documentation/sound/oss/CMI8338 [deleted file]
Documentation/sound/oss/INSTALL.awe [deleted file]
Documentation/sound/oss/MAD16 [deleted file]
Documentation/sound/oss/Maestro [deleted file]
Documentation/sound/oss/Maestro3 [deleted file]
Documentation/sound/oss/NEWS [deleted file]
Documentation/sound/oss/OPL3-SA [deleted file]
Documentation/sound/oss/README.awe [deleted file]
Documentation/sound/oss/Wavefront [deleted file]
Documentation/sound/oss/es1370 [deleted file]
Documentation/sound/oss/rme96xx [deleted file]
Documentation/sound/oss/solo1 [deleted file]
Documentation/sound/oss/sonicvibes [deleted file]
Documentation/sound/oss/ultrasound
Documentation/sound/oss/vwsnd
Documentation/sparc/sbus_drivers.txt
Documentation/spi/pxa2xx
Documentation/spi/spi-summary
Documentation/stable_kernel_rules.txt
Documentation/uml/UserModeLinux-HOWTO.txt
Documentation/unshare.txt
Documentation/usb/URB.txt
Documentation/usb/acm.txt
Documentation/usb/error-codes.txt
Documentation/usb/hiddev.txt
Documentation/usb/mtouchusb.txt
Documentation/usb/usb-serial.txt
Documentation/video4linux/README.pvrusb2
Documentation/video4linux/Zoran
Documentation/video4linux/cx2341x/fw-decoder-api.txt
Documentation/video4linux/cx2341x/fw-encoder-api.txt
Documentation/video4linux/cx2341x/fw-osd-api.txt
Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt
Documentation/video4linux/et61x251.txt
Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
Documentation/video4linux/meye.txt
Documentation/video4linux/sn9c102.txt
Documentation/video4linux/w9968cf.txt
Documentation/video4linux/zr36120.txt
Documentation/vm/numa
Documentation/watchdog/watchdog-api.txt
Documentation/x86_64/boot-options.txt
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/head.S
arch/alpha/kernel/machvec_impl.h
arch/alpha/lib/dbg_stackcheck.S
arch/alpha/lib/dbg_stackkill.S
arch/alpha/lib/memset.S
arch/arm/Kconfig
arch/arm/boot/compressed/head-clps7500.S
arch/arm/common/sa1111.c
arch/arm/mach-imx/leds.c
arch/arm/mach-imx/leds.h
arch/arm/mach-ixp4xx/coyote-pci.c
arch/arm/mach-ixp4xx/ixdpg425-pci.c
arch/arm/mach-lh7a40x/arch-lpd7a40x.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/prcm-regs.h
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/sram-fn.S
arch/arm/mach-pxa/corgi_lcd.c
arch/arm/mach-pxa/leds.h
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/s3c2400-gpio.c
arch/arm/mach-s3c2410/s3c2410-clock.c
arch/arm/mach-s3c2410/s3c2410-gpio.c
arch/arm/mach-s3c2410/s3c2442.c
arch/arm/mach-s3c2410/s3c244x-irq.c
arch/arm/mach-s3c2410/s3c244x.h
arch/arm/mach-s3c2410/usb-simtec.h
arch/arm/mach-sa1100/dma.c
arch/arm/mach-shark/leds.c
arch/arm/plat-omap/sram-fn.S
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v32/Kconfig
arch/h8300/kernel/ints.c
arch/i386/Kconfig
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/efi.c
arch/i386/kernel/i8259.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/ldt.c
arch/i386/kernel/smpboot.c
arch/i386/mach-visws/visws_apic.c
arch/i386/mm/discontig.c
arch/i386/mm/init.c
arch/i386/pci/fixup.c
arch/i386/pci/irq.c
arch/ia64/kernel/Makefile
arch/ia64/kernel/acpi-processor.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/msi_ia64.c [new file with mode: 0644]
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/Makefile
arch/ia64/sn/kernel/msi_sn.c [moved from drivers/pci/msi-altix.c with 65% similarity]
arch/ia64/sn/kernel/xpnet.c
arch/m68k/mm/motorola.c
arch/m68k/sun3/sun3dvma.c
arch/m68knommu/Kconfig
arch/m68knommu/platform/68328/head-pilot.S
arch/mips/dec/prom/call_o32.S
arch/mips/mm/tlbex.c
arch/mips/pci/fixup-vr4133.c
arch/mips/tx4938/common/irq.c
arch/parisc/kernel/entry.S
arch/powerpc/Kconfig
arch/powerpc/boot/Makefile
arch/powerpc/kernel/perfmon_fsl_booke.c
arch/powerpc/oprofile/op_model_7450.c
arch/powerpc/oprofile/op_model_fsl_booke.c
arch/powerpc/platforms/83xx/mpc834x_sys.h
arch/powerpc/platforms/85xx/mpc8540_ads.h
arch/powerpc/platforms/85xx/mpc85xx.h
arch/powerpc/platforms/85xx/mpc85xx_cds.h
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/mpic.c
arch/ppc/Kconfig
arch/ppc/boot/include/mpsc_defs.h
arch/ppc/platforms/4xx/xparameters/xparameters.h
arch/ppc/platforms/85xx/Kconfig
arch/ppc/platforms/lopec.h
arch/ppc/platforms/mpc8272ads_setup.c
arch/ppc/platforms/mpc885ads_setup.c
arch/ppc/platforms/mvme5100.h
arch/ppc/platforms/powerpmc250.h
arch/ppc/platforms/prpmc750.h
arch/ppc/platforms/prpmc800.h
arch/ppc/platforms/spruce.h
arch/sh/boards/bigsur/io.c
arch/sh/boards/bigsur/led.c
arch/sh/boards/ec3104/io.c
arch/sh/boards/hp6xx/setup.c
arch/sh/boards/mpc1211/led.c
arch/sh/boards/mpc1211/setup.c
arch/sh/boards/renesas/hs7751rvoip/io.c
arch/sh/boards/renesas/hs7751rvoip/pci.c
arch/sh/boards/renesas/rts7751r2d/led.c
arch/sh/boards/renesas/systemh/io.c
arch/sh/boards/renesas/systemh/irq.c
arch/sh/boards/renesas/systemh/setup.c
arch/sh/boards/se/770x/led.c
arch/sh/boards/se/7751/led.c
arch/sh/boards/se/7751/pci.c
arch/sh/boards/superh/microdev/io.c
arch/sh/boards/superh/microdev/led.c
arch/sh/drivers/dma/dma-pvr2.c
arch/sh/drivers/pci/dma-dreamcast.c
arch/sh/drivers/pci/fixups-dreamcast.c
arch/sh/drivers/pci/ops-bigsur.c
arch/sh/drivers/pci/ops-dreamcast.c
arch/sh/drivers/pci/ops-rts7751r2d.c
arch/sh/kernel/cpu/ubc.S
arch/sh64/boot/compressed/misc.c
arch/sh64/kernel/alphanum.c
arch/sh64/lib/c-checksum.c
arch/sh64/mach-cayman/led.c
arch/sh64/oprofile/op_model_null.c
arch/sparc/kernel/sys_solaris.c
arch/um/Kconfig
arch/um/Makefile
arch/um/drivers/line.c
arch/um/include/sysdep-x86_64/ptrace_user.h
arch/v850/kernel/entry.S
arch/x86_64/Kconfig
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/mpparse.c
arch/xtensa/Kconfig
arch/xtensa/kernel/module.c
arch/xtensa/kernel/pci-dma.c
arch/xtensa/kernel/pci.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/syscalls.c
arch/xtensa/lib/pci-auto.c
arch/xtensa/lib/usercopy.S
arch/xtensa/mm/pgtable.c
arch/xtensa/mm/tlb.c
drivers/acorn/block/mfmhd.c
drivers/acpi/Kconfig
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_ali.c
drivers/ata/pata_amd.c
drivers/ata/pata_artop.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5520.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cypress.c
drivers/ata/pata_efar.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_hpt3x3.c
drivers/ata/pata_it821x.c
drivers/ata/pata_jmicron.c
drivers/ata/pata_mpiix.c
drivers/ata/pata_netcell.c
drivers/ata/pata_ns87410.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_opti.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_pdc2027x.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_radisys.c
drivers/ata/pata_rz1000.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_serverworks.c
drivers/ata/pata_sil680.c
drivers/ata/pata_sis.c
drivers/ata/pata_sl82c105.c
drivers/ata/pata_triflex.c
drivers/ata/pata_via.c
drivers/ata/pdc_adma.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_sx4.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/block/Kconfig
drivers/block/pktcdvd.c
drivers/cdrom/cdrom.c
drivers/char/amiserial.c
drivers/char/cyclades.c
drivers/char/epca.c
drivers/char/epca.h
drivers/char/generic_serial.c
drivers/char/hw_random/ixp4xx-rng.c
drivers/char/hw_random/omap-rng.c
drivers/char/mwave/README
drivers/char/riscom8.c
drivers/char/serial167.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ixp4xx_wdt.c
drivers/clocksource/scx200_hrt.c
drivers/cpufreq/cpufreq.c
drivers/firmware/Kconfig
drivers/firmware/edd.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-ibm_iic.h
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/scx200_i2c.c
drivers/ide/h8300/ide-h8300.c
drivers/ide/ppc/pmac.c
drivers/ieee1394/Kconfig
drivers/infiniband/ulp/ipoib/Kconfig
drivers/input/joystick/Kconfig
drivers/input/keyboard/Kconfig
drivers/input/serio/Kconfig
drivers/isdn/hardware/eicon/Kconfig
drivers/isdn/hisax/Kconfig
drivers/isdn/hisax/amd7930_fn.h
drivers/isdn/hisax/niccy.c
drivers/leds/led-class.c
drivers/leds/leds-locomo.c
drivers/macintosh/Kconfig
drivers/macintosh/adbhid.c
drivers/md/md.c
drivers/md/raid5.c
drivers/media/dvb/cinergyT2/Kconfig
drivers/media/radio/Kconfig
drivers/media/video/Kconfig
drivers/media/video/cx88/Kconfig
drivers/media/video/pwc/philips.txt
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/tifm_7xx1.c [new file with mode: 0644]
drivers/misc/tifm_core.c [new file with mode: 0644]
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/mmc.c
drivers/mmc/mmc.h
drivers/mmc/mmc_block.c
drivers/mmc/mmc_sysfs.c
drivers/mmc/sdhci.c
drivers/mmc/tifm_sd.c [new file with mode: 0644]
drivers/mtd/chips/Kconfig
drivers/mtd/maps/bast-flash.c
drivers/mtd/maps/dmv182.c
drivers/mtd/nand/Kconfig
drivers/mtd/onenand/Kconfig
drivers/net/Kconfig
drivers/net/arm/am79c961a.h
drivers/net/ibm_emac/ibm_emac_debug.h
drivers/net/ibm_emac/ibm_emac_rgmii.h
drivers/net/tokenring/tmspci.c
drivers/net/wireless/Kconfig
drivers/parisc/power.c
drivers/parport/daisy.c
drivers/pci/Kconfig
drivers/pci/Makefile
drivers/pci/hotplug/Kconfig
drivers/pci/htirq.c [new file with mode: 0644]
drivers/pci/msi-apic.c [deleted file]
drivers/pci/msi.c
drivers/pci/msi.h
drivers/pci/setup-bus.c
drivers/rapidio/Kconfig
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-rs5c372.c
drivers/sbus/char/cpwatchdog.c
drivers/scsi/Kconfig
drivers/scsi/aic7xxx/Kconfig.aic79xx
drivers/scsi/aic7xxx/Kconfig.aic7xxx
drivers/scsi/arm/arxescsi.c
drivers/serial/21285.c
drivers/serial/Kconfig
drivers/serial/cpm_uart/cpm_uart_cpm1.h
drivers/serial/cpm_uart/cpm_uart_cpm2.h
drivers/usb/atm/Kconfig
drivers/usb/core/file.c
drivers/usb/core/usb.c
drivers/usb/gadget/Kconfig
drivers/usb/storage/Kconfig
drivers/video/Kconfig
drivers/video/riva/fbdev.c
drivers/video/s3c2410fb.h
drivers/w1/Kconfig
fs/Kconfig
fs/Makefile
fs/befs/befs_fs_types.h
fs/cifs/README
fs/dcache.c
fs/debugfs/inode.c
fs/ecryptfs/Makefile [new file with mode: 0644]
fs/ecryptfs/crypto.c [new file with mode: 0644]
fs/ecryptfs/debug.c [new file with mode: 0644]
fs/ecryptfs/dentry.c [new file with mode: 0644]
fs/ecryptfs/ecryptfs_kernel.h [new file with mode: 0644]
fs/ecryptfs/file.c [new file with mode: 0644]
fs/ecryptfs/inode.c [new file with mode: 0644]
fs/ecryptfs/keystore.c [new file with mode: 0644]
fs/ecryptfs/main.c [new file with mode: 0644]
fs/ecryptfs/mmap.c [new file with mode: 0644]
fs/ecryptfs/super.c [new file with mode: 0644]
fs/hfsplus/part_tbl.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/host.c
fs/lockd/mon.c
fs/lockd/svc.c
fs/lockd/svc4proc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/lockd/svcshare.c
fs/lockd/svcsubs.c
fs/nfsd/export.c
fs/nfsd/nfs2acl.c
fs/nfsd/nfs3acl.c
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4acl.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
fs/nfsd/nfsxdr.c
fs/nfsd/vfs.c
fs/nls/nls_ascii.c
fs/nls/nls_base.c
fs/nls/nls_cp1250.c
fs/nls/nls_cp1251.c
fs/nls/nls_cp1255.c
fs/nls/nls_cp437.c
fs/nls/nls_cp737.c
fs/nls/nls_cp775.c
fs/nls/nls_cp850.c
fs/nls/nls_cp852.c
fs/nls/nls_cp855.c
fs/nls/nls_cp857.c
fs/nls/nls_cp860.c
fs/nls/nls_cp861.c
fs/nls/nls_cp862.c
fs/nls/nls_cp863.c
fs/nls/nls_cp864.c
fs/nls/nls_cp865.c
fs/nls/nls_cp866.c
fs/nls/nls_cp869.c
fs/nls/nls_cp874.c
fs/nls/nls_cp932.c
fs/nls/nls_cp936.c
fs/nls/nls_cp949.c
fs/nls/nls_cp950.c
fs/nls/nls_euc-jp.c
fs/nls/nls_iso8859-1.c
fs/nls/nls_iso8859-13.c
fs/nls/nls_iso8859-14.c
fs/nls/nls_iso8859-15.c
fs/nls/nls_iso8859-2.c
fs/nls/nls_iso8859-3.c
fs/nls/nls_iso8859-4.c
fs/nls/nls_iso8859-5.c
fs/nls/nls_iso8859-6.c
fs/nls/nls_iso8859-7.c
fs/nls/nls_iso8859-9.c
fs/nls/nls_koi8-r.c
fs/nls/nls_koi8-ru.c
fs/nls/nls_koi8-u.c
fs/reiserfs/file.c
fs/reiserfs/inode.c
fs/reiserfs/item_ops.c
fs/reiserfs/journal.c
fs/reiserfs/namei.c
fs/reiserfs/stree.c
fs/xfs/support/debug.c
include/asm-arm/arch-clps711x/entry-macro.S
include/asm-arm/arch-ebsa285/entry-macro.S
include/asm-arm/arch-h720x/system.h
include/asm-arm/arch-ixp4xx/system.h
include/asm-arm/arch-omap/dmtimer.h
include/asm-arm/arch-omap/mcbsp.h
include/asm-arm/arch-omap/pm.h
include/asm-arm/arch-pnx4008/platform.h
include/asm-arm/arch-s3c2410/fb.h
include/asm-arm/arch-s3c2410/regs-adc.h
include/asm-arm/arch-s3c2410/regs-clock.h
include/asm-arm/arch-s3c2410/regs-dsc.h
include/asm-arm/arch-s3c2410/regs-gpio.h
include/asm-arm/arch-s3c2410/regs-gpioj.h
include/asm-arm/arch-s3c2410/regs-iis.h
include/asm-arm/arch-s3c2410/regs-irq.h
include/asm-arm/arch-s3c2410/regs-lcd.h
include/asm-arm/arch-s3c2410/regs-rtc.h
include/asm-arm/arch-s3c2410/regs-sdi.h
include/asm-arm/arch-s3c2410/regs-timer.h
include/asm-arm/arch-s3c2410/regs-udc.h
include/asm-arm/arch-s3c2410/spi-gpio.h
include/asm-arm/arch-sa1100/neponset.h
include/asm-arm/arch-sa1100/uncompress.h
include/asm-arm/arch-shark/vmalloc.h
include/asm-arm/hardware/debug-8250.S
include/asm-arm/hardware/debug-pl01x.S
include/asm-arm/hardware/entry-macro-iomd.S
include/asm-arm/hardware/sa1111.h
include/asm-arm26/assembler.h
include/asm-arm26/namei.h
include/asm-arm26/semaphore.h
include/asm-frv/namei.h
include/asm-generic/mutex-dec.h
include/asm-generic/mutex-null.h
include/asm-generic/mutex-xchg.h
include/asm-generic/rtc.h
include/asm-generic/tlb.h
include/asm-i386/hw_irq.h
include/asm-i386/hypertransport.h [new file with mode: 0644]
include/asm-i386/io_apic.h
include/asm-i386/mach-default/irq_vectors_limits.h
include/asm-i386/mach-summit/mach_apic.h
include/asm-i386/msi.h [deleted file]
include/asm-i386/msidef.h [new file with mode: 0644]
include/asm-ia64/machvec.h
include/asm-ia64/machvec_sn2.h
include/asm-ia64/msi.h [deleted file]
include/asm-m32r/m32104ut/m32104ut_pld.h
include/asm-m32r/m32700ut/m32700ut_lan.h
include/asm-m32r/m32700ut/m32700ut_lcd.h
include/asm-m32r/m32700ut/m32700ut_pld.h
include/asm-m32r/mappi2/mappi2_pld.h
include/asm-m32r/mappi3/mappi3_pld.h
include/asm-m32r/opsput/opsput_lan.h
include/asm-m32r/opsput/opsput_lcd.h
include/asm-m32r/opsput/opsput_pld.h
include/asm-m68k/rtc.h
include/asm-m68knommu/processor.h
include/asm-mips/tx4938/tx4938_mips.h
include/asm-parisc/rtc.h
include/asm-powerpc/ipic.h
include/asm-ppc/mv64x60_defs.h
include/asm-ppc/rheap.h
include/asm-ppc/rtc.h
include/asm-s390/qdio.h
include/asm-sh/bigsur/io.h
include/asm-sh/bigsur/serial.h
include/asm-sh/dreamcast/sysasic.h
include/asm-sh/hd64465/io.h
include/asm-sh/mpc1211/io.h
include/asm-sh64/serial.h
include/asm-sparc/reg.h
include/asm-x86_64/cache.h
include/asm-x86_64/hardirq.h
include/asm-x86_64/hw_irq.h
include/asm-x86_64/hypertransport.h [new file with mode: 0644]
include/asm-x86_64/io_apic.h
include/asm-x86_64/irq.h
include/asm-x86_64/msi.h [deleted file]
include/asm-x86_64/msidef.h [new file with mode: 0644]
include/asm-xtensa/a.out.h
include/asm-xtensa/cache.h
include/asm-xtensa/coprocessor.h
include/asm-xtensa/dma-mapping.h
include/asm-xtensa/ioctls.h
include/asm-xtensa/pgtable.h
include/asm-xtensa/siginfo.h
include/linux/Kbuild
include/linux/ac97_codec.h
include/linux/aio_abi.h
include/linux/audit.h
include/linux/awe_voice.h
include/linux/hardirq.h
include/linux/harrier_defs.h
include/linux/htirq.h [new file with mode: 0644]
include/linux/ipc.h
include/linux/irq.h
include/linux/libata.h
include/linux/lockd/lockd.h
include/linux/lockd/share.h
include/linux/lockd/sm_inter.h
include/linux/lockd/xdr4.h
include/linux/msi.h [new file with mode: 0644]
include/linux/mtd/plat-ram.h
include/linux/nfsd/const.h
include/linux/nfsd/export.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/stats.h
include/linux/nfsd/xdr.h
include/linux/nfsd/xdr3.h
include/linux/nfsd/xdr4.h
include/linux/notifier.h
include/linux/pci.h
include/linux/pci_regs.h
include/linux/ppdev.h
include/linux/rcupdate.h
include/linux/scx200.h
include/linux/slab.h
include/linux/sound.h
include/linux/srcu.h [new file with mode: 0644]
include/linux/sunrpc/auth.h
include/linux/sunrpc/auth_gss.h
include/linux/sunrpc/cache.h
include/linux/sunrpc/gss_api.h
include/linux/sunrpc/msg_prot.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcauth.h
include/linux/sunrpc/svcauth_gss.h
include/linux/sunrpc/svcsock.h
include/linux/sunrpc/xprt.h
include/linux/tifm.h [new file with mode: 0644]
include/linux/utsname.h
include/linux/wavefront.h [deleted file]
include/linux/writeback.h
include/video/s1d13xxxfb.h
ipc/mqueue.c
ipc/msgutil.c
kernel/Makefile
kernel/auditfilter.c
kernel/auditsc.c
kernel/irq/chip.c
kernel/irq/migration.c
kernel/posix-timers.c
kernel/rcupdate.c
kernel/rcutorture.c
kernel/srcu.c [new file with mode: 0644]
kernel/sys.c
kernel/workqueue.c
lib/reed_solomon/reed_solomon.c
mm/Kconfig
mm/filemap.c
mm/hugetlb.c
mm/nommu.c
mm/page-writeback.c
mm/page_alloc.c
mm/slab.c
mm/util.c
mm/vmalloc.c
net/core/skbuff.c
net/ipv4/Kconfig
net/ipv4/arp.c
net/ipv4/ipvs/Kconfig
net/ipv4/netfilter/Kconfig
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/svc.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
scripts/Makefile.headersinst
scripts/kernel-doc
security/selinux/Kconfig
sound/oss/Kconfig
sound/oss/Makefile
sound/oss/ac97.c
sound/oss/ac97.h
sound/oss/ac97_codec.c
sound/oss/ac97_plugin_ad1980.c [deleted file]
sound/oss/ad1848.c
sound/oss/ad1848.h
sound/oss/ad1848_mixer.h
sound/oss/adlib_card.c
sound/oss/ali5455.c [deleted file]
sound/oss/au1000.c [deleted file]
sound/oss/audio.c
sound/oss/audio_syms.c [deleted file]
sound/oss/awe_hw.h [deleted file]
sound/oss/awe_wave.c [deleted file]
sound/oss/awe_wave.h [deleted file]
sound/oss/cmpci.c [deleted file]
sound/oss/cs4281/Makefile [deleted file]
sound/oss/cs4281/cs4281_hwdefs.h [deleted file]
sound/oss/cs4281/cs4281_wrapper-24.c [deleted file]
sound/oss/cs4281/cs4281m.c [deleted file]
sound/oss/cs4281/cs4281pm-24.c [deleted file]
sound/oss/cs4281/cs4281pm.h [deleted file]
sound/oss/dev_table.c
sound/oss/dev_table.h
sound/oss/dm.h [deleted file]
sound/oss/dmabuf.c
sound/oss/es1370.c [deleted file]
sound/oss/esssolo1.c [deleted file]
sound/oss/forte.c [deleted file]
sound/oss/gus.h [deleted file]
sound/oss/gus_card.c [deleted file]
sound/oss/gus_hw.h [deleted file]
sound/oss/gus_linearvol.h [deleted file]
sound/oss/gus_midi.c [deleted file]
sound/oss/gus_vol.c [deleted file]
sound/oss/gus_wave.c [deleted file]
sound/oss/harmony.c [deleted file]
sound/oss/ics2101.c [deleted file]
sound/oss/iwmem.h [deleted file]
sound/oss/mad16.c [deleted file]
sound/oss/maestro.c [deleted file]
sound/oss/maestro.h [deleted file]
sound/oss/maestro3.c [deleted file]
sound/oss/maestro3.h [deleted file]
sound/oss/maui.c [deleted file]
sound/oss/midi_syms.c [deleted file]
sound/oss/midi_synth.c
sound/oss/midibuf.c
sound/oss/mpu401.c
sound/oss/mpu401.h
sound/oss/opl3.c
sound/oss/opl3sa.c [deleted file]
sound/oss/opl3sa2.c
sound/oss/pas2_card.c
sound/oss/pas2_midi.c
sound/oss/pas2_mixer.c
sound/oss/pss.c
sound/oss/rme96xx.c [deleted file]
sound/oss/rme96xx.h [deleted file]
sound/oss/sb_audio.c
sound/oss/sb_common.c
sound/oss/sb_midi.c
sound/oss/sb_mixer.c
sound/oss/sb_mixer.h
sound/oss/sequencer.c
sound/oss/sequencer_syms.c [deleted file]
sound/oss/sgalaxy.c [deleted file]
sound/oss/sonicvibes.c [deleted file]
sound/oss/sound_calls.h
sound/oss/sound_syms.c [deleted file]
sound/oss/sound_timer.c
sound/oss/soundcard.c
sound/oss/sscape.c
sound/oss/sys_timer.c
sound/oss/trix.c
sound/oss/tuning.h
sound/oss/uart401.c
sound/oss/uart6850.c
sound/oss/v_midi.c
sound/oss/waveartist.c
sound/oss/waveartist.h
sound/oss/wavfront.c [deleted file]
sound/oss/wf_midi.c [deleted file]
sound/oss/ymfpci.c [deleted file]
sound/oss/ymfpci.h [deleted file]
sound/oss/ymfpci_image.h [deleted file]
sound/oss/yss225.c [deleted file]
sound/oss/yss225.h [deleted file]
sound/sound_core.c

diff --git a/CREDITS b/CREDITS
index 6c06ded9882b39300e76f2cea4d57f78ff47f752..5d75254bcb8135d339d98a7a8002e7c09a99dc4a 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -34,6 +34,7 @@ E: magrawal@nortelnetworks.com
 D: Basic Interphase 5575 driver with UBR and ABR support.
 S: 75 Donald St, Apt 42
 S: Weymouth, MA 02188
+S: USA
 
 N: Dave Airlie
 E: airlied@linux.ie
@@ -202,6 +203,7 @@ S: MS42
 S: Hewlett-Packard
 S: 3404 E Harmony Rd
 S: Fort Collins, CO 80525
+S: USA
 
 N: Arindam Banerji
 E: axb@cse.nd.edu
@@ -444,6 +446,7 @@ E: rbradetich@uswest.net
 D: Linux/PA-RISC hacker
 S: 1200 Goldenrod Dr.
 S: Nampa, Idaho 83686
+S: USA
 
 N: Derrick J. Brashear
 E: shadow@dementia.org
@@ -633,6 +636,7 @@ E: scole@lanl.gov
 E: elenstev@mesatop.com
 D: Various build fixes and kernel documentation.
 S: Los Alamos, New Mexico
+S: USA
 
 N: Hamish Coleman
 E: hamish@zot.apana.org.au
@@ -2009,6 +2013,7 @@ W: http://www.mathematik.uni-stuttgart.de/~floeff
 D: Busmaster driver for HP 10/100 Mbit Network Adapters
 S: University of Stuttgart, Germany and
 S: Ecole Nationale Superieure des Telecommunications, Paris
+S: France
 
 N: Jamie Lokier
 E: jamie@shareable.org
@@ -2178,6 +2183,7 @@ S: Hewlett Packard
 S: MS 42
 S: 3404 E. Harmony Road
 S: Fort Collins, CO 80528
+S: USA
 
 N: Torben Mathiasen
 E: torben.mathiasen@compaq.com
@@ -2234,6 +2240,12 @@ D: tc: HFSC scheduler
 S: Freiburg
 S: Germany
 
+N: Paul E. McKenney
+E: paulmck@us.ibm.com
+W: http://www.rdrop.com/users/paulmck/
+D: RCU and variants
+D: rcutorture module
+
 N: Mike McLagan
 E: mike.mclagan@linux.org
 W: http://www.invlogic.com/~mmclagan
@@ -2975,6 +2987,10 @@ S: 69 rue Dunois
 S: 75013 Paris
 S: France
 
+N: Dipankar Sarma
+E: dipankar@in.ibm.com
+D: RCU
+
 N: Hannu Savolainen
 E: hannu@opensound.com
 D: Maintainer of the sound drivers until 2.1.x days.
@@ -3287,6 +3303,12 @@ S: 3 Ballow Crescent
 S: MacGregor A.C.T 2615
 S: Australia
 
+N: Josh Triplett
+E: josh@freedesktop.org
+P: 1024D/D0FE7AFB B24A 65C9 1D71 2AC2 DE87  CA26 189B 9946 D0FE 7AFB
+D: rcutorture maintainer
+D: lock annotations, finding and fixing lock bugs
+
 N: Winfried Trümper
 E: winni@xpilot.org
 W: http://www.shop.de/~winni/
@@ -3658,7 +3680,7 @@ S: Portland, OR
 S: USA
 
 N: Michal Wronski
-E: Michal.Wronski@motorola.com
+E: michal.wronski@gmail.com
 D: POSIX message queues fs (with K. Benedyczak)
 S: Krakow
 S: Poland
index 63392c9132b4d08bf32f3fab82cc0c14c39e15b1..028614cdd0624291f630d3cdda899cf02335ed2b 100644 (file)
@@ -107,7 +107,7 @@ The query is performed via a call to pci_set_dma_mask():
 
        int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
 
-The query for consistent allocations is performed via a call to
+The query for consistent allocations is performed via a call to
 pci_set_consistent_dma_mask():
 
        int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
@@ -117,7 +117,7 @@ device_mask is a bit mask describing which bits of a PCI address your
 device supports.  It returns zero if your card can perform DMA
 properly on the machine given the address mask you provided.
 
-If it returns non-zero, your device can not perform DMA properly on
+If it returns non-zero, your device cannot perform DMA properly on
 this platform, and attempting to do so will result in undefined
 behavior.  You must either use a different mask, or not use DMA.
 
index 49c745720f47360edba2a19b0f441233acf317a2..2b5ac604948c8b4a80e46735d279117490a95409 100644 (file)
@@ -158,6 +158,7 @@ X!Ilib/string.c
 !Emm/filemap.c
 !Emm/memory.c
 !Emm/vmalloc.c
+!Imm/page_alloc.c
 !Emm/mempool.c
 !Emm/page-writeback.c
 !Emm/truncate.c
index 065e8dc23e3adb4bd3d5d659ddf2a80741261b3a..07a635590b36e8ff8c8a61086adb34e9d907bd65 100644 (file)
@@ -14,7 +14,7 @@
   </authorgroup>
 
   <copyright>
-   <year>2003-2005</year>
+   <year>2003-2006</year>
    <holder>Jeff Garzik</holder>
   </copyright>
 
@@ -1400,7 +1400,7 @@ and other resources, etc.
        <listitem>
        <para>
        When it's known that HBA is in ready state but ATA/ATAPI
-       device in in unknown state, reset only device.
+       device is in unknown state, reset only device.
        </para>
        </listitem>
 
index 3608472d7b7450ef291d07e8fb1dd4de69a9dbdf..143e5ff7deb8c4fad66789c02750749251a2acea 100644 (file)
        <emphasis>usbdevfs</emphasis> although it wasn't solving what
        <emphasis>devfs</emphasis> was.
        Every USB device will appear in usbfs, regardless of whether or
-       not it has a kernel driver; but only devices with kernel drivers
-       show up in devfs.
+       not it has a kernel driver.
        </para>
 
        <sect1>
@@ -741,7 +740,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param)
                <title>Synchronous I/O Support</title>
 
                <para>Synchronous requests involve the kernel blocking
-               until until the user mode request completes, either by
+               until the user mode request completes, either by
                finishing successfully or by reporting an error.
                In most cases this is the simplest way to use usbfs,
                although as noted above it does prevent performing I/O
index 008a341234d0ca48848b216038fc0f900d235b0e..07cd34c1940b446a41ae0eb8f2f7d76698670f65 100644 (file)
@@ -224,13 +224,8 @@ static int skel_probe(struct usb_interface *interface,
      Conversely, when the device is removed from the USB bus, the disconnect
      function is called with the device pointer. The driver needs to clean any
      private data that has been allocated at this time and to shut down any
-     pending urbs that are in the USB system. The driver also unregisters
-     itself from the devfs subsystem with the call:
+     pending urbs that are in the USB system.
   </para>
-  <programlisting>
-/* remove our devfs node */
-devfs_unregister(skel->devfs);
-  </programlisting>
   <para>
      Now that the device is plugged into the system and the driver is bound to
      the device, any of the functions in the file_operations structure that
index 9f08d73d90bf12251770e0d22bd8cd1a2c18a70e..0e3924ecd76b4e9b197348d656712fee80a2691d 100644 (file)
@@ -468,12 +468,12 @@ BMCs specified on the smb_addr line will be detected.
 Setting smb_dbg_probe to 1 will enable debugging of the probing and
 detection process for BMCs on the SMBusses.
 
-Discovering the IPMI compilant BMC on the SMBus can cause devices
+Discovering the IPMI compliant BMC on the SMBus can cause devices
 on the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI
 message as a block write to the I2C bus and waits for a response.
 This action can be detrimental to some I2C devices. It is highly recommended
 that the known I2c address be given to the SMBus driver in the smb_addr
-parameter. The default adrress range will not be used when a smb_addr
+parameter. The default address range will not be used when a smb_addr
 parameter is provided.
 
 When compiled into the kernel, the addresses can be specified on the
index 3ec6c720b0166b4a76c576391414c795898d47b5..c70306abb7b2e2c4fc306bdc70447b47c9e9878e 100644 (file)
@@ -267,7 +267,7 @@ y = The number of MSI capable devices populated in the system.
        vector reserved to avoid the case where some MSI-X capable
        drivers may attempt to claim all available vector resources.
 
-z =    The number of MSI-X capable devices pupulated in the system.
+z =    The number of MSI-X capable devices populated in the system.
        This policy ensures that maximum (x - y) is distributed
        evenly among MSI-X capable devices.
 
index 1d50cf0c905ef28d62d6e5eda83c6415721504a6..f4dffadbcb00af44b40b99dd55649731b57cb21d 100644 (file)
@@ -221,3 +221,41 @@ over a rather long period of time, but improvements are always welcome!
        disable irq on a given acquisition of that lock will result in
        deadlock as soon as the RCU callback happens to interrupt that
        acquisition's critical section.
+
+13.    SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
+       may only be invoked from process context.  Unlike other forms of
+       RCU, it -is- permissible to block in an SRCU read-side critical
+       section (demarked by srcu_read_lock() and srcu_read_unlock()),
+       hence the "SRCU": "sleepable RCU".  Please note that if you
+       don't need to sleep in read-side critical sections, you should
+       be using RCU rather than SRCU, because RCU is almost always
+       faster and easier to use than is SRCU.
+
+       Also unlike other forms of RCU, explicit initialization
+       and cleanup is required via init_srcu_struct() and
+       cleanup_srcu_struct().  These are passed a "struct srcu_struct"
+       that defines the scope of a given SRCU domain.  Once initialized,
+       the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
+       and synchronize_srcu().  A given synchronize_srcu() waits only
+       for SRCU read-side critical sections governed by srcu_read_lock()
+       and srcu_read_unlock() calls that have been passd the same
+       srcu_struct.  This property is what makes sleeping read-side
+       critical sections tolerable -- a given subsystem delays only
+       its own updates, not those of other subsystems using SRCU.
+       Therefore, SRCU is less prone to OOM the system than RCU would
+       be if RCU's read-side critical sections were permitted to
+       sleep.
+
+       The ability to sleep in read-side critical sections does not
+       come for free.  First, corresponding srcu_read_lock() and
+       srcu_read_unlock() calls must be passed the same srcu_struct.
+       Second, grace-period-detection overhead is amortized only
+       over those updates sharing a given srcu_struct, rather than
+       being globally amortized as they are for other forms of RCU.
+       Therefore, SRCU should be used in preference to rw_semaphore
+       only in extremely read-intensive situations, or in situations
+       requiring SRCU's read-side deadlock immunity or low read-side
+       realtime latency.
+
+       Note that, rcu_assign_pointer() and rcu_dereference() relate to
+       SRCU just as they do to other forms of RCU.
index 02e27bf1d36554d35038bdb6c962c2f091618d0a..f84407cba8160a47ea57e46a640a54efafb905c5 100644 (file)
@@ -45,7 +45,8 @@ o     How can I see where RCU is currently used in the Linux kernel?
 
        Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu",
        "rcu_read_lock_bh", "rcu_read_unlock_bh", "call_rcu_bh",
-       "synchronize_rcu", and "synchronize_net".
+       "srcu_read_lock", "srcu_read_unlock", "synchronize_rcu",
+       "synchronize_net", and "synchronize_srcu".
 
 o      What guidelines should I follow when writing code that uses RCU?
 
index a4948591607d0e1d7b653ce1f66c08e4831cbad1..25a3c3f7d378f344676652aec19fad62853fc6b1 100644 (file)
@@ -28,6 +28,15 @@ nreaders     This is the number of RCU reading threads supported.
                To properly exercise RCU implementations with preemptible
                read-side critical sections.
 
+nfakewriters   This is the number of RCU fake writer threads to run.  Fake
+               writer threads repeatedly use the synchronous "wait for
+               current readers" function of the interface selected by
+               torture_type, with a delay between calls to allow for various
+               different numbers of writers running in parallel.
+               nfakewriters defaults to 4, which provides enough parallelism
+               to trigger special cases caused by multiple writers, such as
+               the synchronize_srcu() early return optimization.
+
 stat_interval  The number of seconds between output of torture
                statistics (via printk()).  Regardless of the interval,
                statistics are printed when the module is unloaded.
@@ -44,9 +53,12 @@ test_no_idle_hz      Whether or not to test the ability of RCU to operate in
                a kernel that disables the scheduling-clock interrupt to
                idle CPUs.  Boolean parameter, "1" to test, "0" otherwise.
 
-torture_type   The type of RCU to test: "rcu" for the rcu_read_lock()
-               API, "rcu_bh" for the rcu_read_lock_bh() API, and "srcu"
-               for the "srcu_read_lock()" API.
+torture_type   The type of RCU to test: "rcu" for the rcu_read_lock() API,
+               "rcu_sync" for rcu_read_lock() with synchronous reclamation,
+               "rcu_bh" for the rcu_read_lock_bh() API, "rcu_bh_sync" for
+               rcu_read_lock_bh() with synchronous reclamation, "srcu" for
+               the "srcu_read_lock()" API, and "sched" for the use of
+               preempt_disable() together with synchronize_sched().
 
 verbose                Enable debug printk()s.  Default is disabled.
 
@@ -118,6 +130,21 @@ o  "Free-Block Circulation": Shows the number of torture structures
        as it is only incremented if a torture structure's counter
        somehow gets incremented farther than it should.
 
+Different implementations of RCU can provide implementation-specific
+additional information.  For example, SRCU provides the following:
+
+       srcu-torture: rtc: f8cf46a8 ver: 355 tfle: 0 rta: 356 rtaf: 0 rtf: 346 rtmbe: 0
+       srcu-torture: Reader Pipe:  559738 939 0 0 0 0 0 0 0 0 0
+       srcu-torture: Reader Batch:  560434 243 0 0 0 0 0 0 0 0
+       srcu-torture: Free-Block Circulation:  355 354 353 352 351 350 349 348 347 346 0
+       srcu-torture: per-CPU(idx=1): 0(0,1) 1(0,1) 2(0,0) 3(0,1)
+
+The first four lines are similar to those for RCU.  The last line shows
+the per-CPU counter state.  The numbers in parentheses are the values
+of the "old" and "current" counters for the corresponding CPU.  The
+"idx" value maps the "old" and "current" values to the underlying array,
+and is useful for debugging.
+
 
 USAGE
 
index 318df44259b37f6556cbe5b6b4e9e12d4a26259a..e0d6d99b8f9bb0dc17f647dbd8256aad1282dd2d 100644 (file)
@@ -582,7 +582,7 @@ The rcu_read_lock() and rcu_read_unlock() primitive read-acquire
 and release a global reader-writer lock.  The synchronize_rcu()
 primitive write-acquires this same lock, then immediately releases
 it.  This means that once synchronize_rcu() exits, all RCU read-side
-critical sections that were in progress before synchonize_rcu() was
+critical sections that were in progress before synchronize_rcu() was
 called are guaranteed to have completed -- there is no way that
 synchronize_rcu() would have been able to write-acquire the lock
 otherwise.
@@ -750,7 +750,7 @@ Or, for those who prefer a side-by-side listing:
 
 Either way, the differences are quite small.  Read-side locking moves
 to rcu_read_lock() and rcu_read_unlock, update-side locking moves from
-from a reader-writer lock to a simple spinlock, and a synchronize_rcu()
+a reader-writer lock to a simple spinlock, and a synchronize_rcu()
 precedes the kfree().
 
 However, there is one potential catch: the read-side and update-side
@@ -778,6 +778,8 @@ Markers for RCU read-side critical sections:
        rcu_read_unlock
        rcu_read_lock_bh
        rcu_read_unlock_bh
+       srcu_read_lock
+       srcu_read_unlock
 
 RCU pointer/list traversal:
 
@@ -804,6 +806,7 @@ RCU grace period:
        synchronize_net
        synchronize_sched
        synchronize_rcu
+       synchronize_srcu
        call_rcu
        call_rcu_bh
 
index 7fee1e1165bcf0a563176fd340be41e9d248e860..c09dfad4aed8f95be03a5088cdb7f824c8f3f774 100644 (file)
@@ -7,7 +7,7 @@ not been observed, but it would be nice to eliminate any potential for
 deadlock under memory pressure.
 
 Because ATA over Ethernet is not fragmented by the kernel's IP code,
-the destructore member of the struct sk_buff is available to the aoe
+the destructor member of the struct sk_buff is available to the aoe
 driver.  By using a mempool for allocating all but the first few
 sk_buffs, and by registering a destructor, we should be able to
 efficiently allocate sk_buffs without introducing any potential for
index aea2e91ca0efe96fb1783e0a84b586a625308cda..a63966f1d08358414c339c5d6dbc7782be4131c8 100644 (file)
@@ -24,8 +24,8 @@ The SA1100 serial port had its major/minor numbers officially assigned:
 >                   7 = /dev/cusa2                Callout device for ttySA2
 >
 
-If you're not using devfs, you must create those inodes in /dev
-on the root filesystem used by your SA1100-based device:
+You must create those inodes in /dev on the root filesystem used
+by your SA1100-based device:
 
        mknod ttySA0 c 204 5
        mknod ttySA1 c 204 6
index 000e3d7a78b23cd27fc74ce0eccdec7681a6ef81..26422f0f9080386dd5c3a8986757b14eb3df5d1e 100644 (file)
@@ -38,7 +38,7 @@ MTD
 ---
 
   The NAND and NOR support has been merged from the linux-mtd project.
-  Any prolbems, see http://www.linux-mtd.infradead.org/ for more
+  Any problems, see http://www.linux-mtd.infradead.org/ for more
   information or up-to-date versions of linux-mtd.
 
 
index 0822764ec2708ecd826518ba5c21d6f34564e59e..8caea8c237eec0b9a033414c53ab2ea30b313800 100644 (file)
@@ -24,7 +24,7 @@ Headers
   header include/asm-arm/arch-s3c2410/hardware.h which can be
   included by #include <asm/arch/hardware.h>
 
-  A useful ammount of documentation can be found in the hardware
+  A useful amount of documentation can be found in the hardware
   header on how the GPIO functions (and others) work.
 
   Whilst a number of these functions do make some checks on what
index 3e46d2a3115814a67e6990a9bba8e09e77f80854..dda7ecdde87bab1de56867759f2a3aaab246db3d 100644 (file)
@@ -80,7 +80,7 @@ Machines
 Adding New Machines
 -------------------
 
-  The archicture has been designed to support as many machines as can
+  The architecture has been designed to support as many machines as can
   be configured for it in one kernel build, and any future additions
   should keep this in mind before altering items outside of their own
   machine files.
index cb82a7fc7901302d50958532e6fb0994980ab8a3..295d971a15ed49d1c7d60fb31affbdd1e5119a1c 100644 (file)
@@ -80,7 +80,7 @@ RTC
 Watchdog
 --------
 
-  The watchdog harware is the same as the S3C2410, and is supported by
+  The watchdog hardware is the same as the S3C2410, and is supported by
   the s3c2410_wdt driver.
 
 
index 6f47332c883de7366d7d8f73fa5036d55136480c..e2a66f8143c5c63b0b780ee13fc1069b87c82011 100644 (file)
@@ -99,8 +99,8 @@ contrast, many write requests may be dispatched to the disk controller
 at a time during a write batch.  It is this characteristic that can make
 the anticipatory scheduler perform anomalously with controllers supporting
 TCQ, or with hardware striped RAID devices. Setting the antic_expire
-queue paramter (see below) to zero disables this behavior, and the anticipatory
-scheduler behaves essentially like the deadline scheduler.
+queue parameter (see below) to zero disables this behavior, and the 
+anticipatory scheduler behaves essentially like the deadline scheduler.
 
 When read anticipation is enabled (antic_expire is not zero), reads
 are dispatched to the disk controller one at a time.
index 03971518b22254781bce94bea5c749f0a2cd1e7f..a272c3db80940bd5821e8b2f28068e3fe5d5a65b 100644 (file)
@@ -25,7 +25,7 @@ of the following three ways.
 i. For devices which have queue depth greater than 1 (TCQ devices) and
 support ordered tags, block layer can just issue the barrier as an
 ordered request and the lower level driver, controller and drive
-itself are responsible for making sure that the ordering contraint is
+itself are responsible for making sure that the ordering constraint is
 met.  Most modern SCSI controllers/drives should support this.
 
 NOTE: SCSI ordered tag isn't currently used due to limitation in the
@@ -42,7 +42,7 @@ iii. Devices which have queue depth of 1.  This is a degenerate case
 of ii.  Just keeping issue order suffices.  Ancient SCSI
 controllers/drives and IDE drives are in this category.
 
-2. Forced flushing to physcial medium
+2. Forced flushing to physical medium
 
 Again, if you're not gonna do synchronization with disk drives (dang,
 it sounds even more appealing now!), the reason you use I/O barriers
@@ -56,7 +56,7 @@ There are four cases,
 i. No write-back cache.  Keeping requests ordered is enough.
 
 ii. Write-back cache but no flush operation.  There's no way to
-gurantee physical-medium commit order.  This kind of devices can't to
+guarantee physical-medium commit order.  This kind of devices can't to
 I/O barriers.
 
 iii. Write-back cache and flush operation but no FUA (forced unit
index f989a9e839b49abde7b12bfea3926aca9b3635a3..34bf8f60d8f827a9b83f27747c265a27fe38928d 100644 (file)
@@ -135,7 +135,7 @@ Some new queue property settings:
                Sets two variables that limit the size of the request.
 
                - The request queue's max_sectors, which is a soft size in
-               in units of 512 byte sectors, and could be dynamically varied
+               units of 512 byte sectors, and could be dynamically varied
                by the core kernel.
 
                - The request queue's max_hw_sectors, which is a hard limit
@@ -783,7 +783,7 @@ all the outstanding requests. There's a third helper to do that:
 
        blk_queue_invalidate_tags(request_queue_t *q)
 
-       Clear the internal block tag queue and readd all the pending requests
+       Clear the internal block tag queue and re-add all the pending requests
        to the request queue. The driver will receive them again on the
        next request_fn run, just like it did the first time it encountered
        them.
@@ -890,7 +890,7 @@ Aside:
 
   Kvec i/o:
 
-  Ben LaHaise's aio code uses a slighly different structure instead
+  Ben LaHaise's aio code uses a slightly different structure instead
   of kiobufs, called a kvec_cb. This contains an array of <page, offset, len>
   tuples (very much like the networking code), together with a callback function
   and data pointer. This is embedded into a brw_cb structure when passed
@@ -988,7 +988,7 @@ elevator_exit_fn            Allocate and free any elevator specific storage
                                for a queue.
 
 4.2 Request flows seen by I/O schedulers
-All requests seens by I/O schedulers strictly follow one of the following three
+All requests seen by I/O schedulers strictly follow one of the following three
 flows.
 
  set_req_fn ->
@@ -1203,6 +1203,6 @@ temporarily map a bio into the virtual address space.
 and Linus' comments - Jan 2001)
 9.2 Discussions about kiobuf and bh design on lkml between sct, linus, alan
 et al - Feb-March 2001 (many of the initial thoughts that led to bio were
-brought up in this discusion thread)
+brought up in this discussion thread)
 9.3 Discussions on mempool on lkml - Dec 2001.
 
index c918b3a6022dd04c48f396d81c372c7d7538a682..be08ffd1e9b82a52504c05ad657ebb4bd895d80b 100644 (file)
@@ -23,11 +23,11 @@ you can do so by typing:
 read_expire    (in ms)
 -----------
 
-The goal of the deadline io scheduler is to attempt to guarentee a start
+The goal of the deadline io scheduler is to attempt to guarantee a start
 service time for a request. As we focus mainly on read latencies, this is
 tunable. When a read request first enters the io scheduler, it is assigned
 a deadline that is the current time + the read_expire value in units of
-miliseconds.
+milliseconds.
 
 
 write_expire   (in ms)
index 9c629ffa0e58ffa5710843a5c389660d46036681..f74affe5c8297f58b4d36dfac566e7411899f2c5 100644 (file)
@@ -80,7 +80,7 @@ the /proc filesystem entry which the "block" side of the driver creates as
 the SCSI core may not yet be initialized (because the driver is a block 
 driver) and attempting to register it with the SCSI core in such a case 
 would cause a hang.  This is best done via an initialization script 
-(typically in /etc/init.d, but could vary depending on distibution). 
+(typically in /etc/init.d, but could vary depending on distribution). 
 For example:
 
        for x in /proc/driver/cciss/cciss[0-9]*
@@ -152,7 +152,7 @@ side during the SCSI error recovery process, the cciss driver only
 implements the first two of these actions, aborting the command, and
 resetting the device.  Additionally, most tape drives will not oblige 
 in aborting commands, and sometimes it appears they will not even 
-obey a reset coommand, though in most circumstances they will.  In
+obey a reset command, though in most circumstances they will.  In
 the case that the command cannot be aborted and the device cannot be 
 reset, the device will be set offline.
 
index b1cf59b84d9727f718b434f0c128511dace766df..5e2a0c76bfa0b61a697772496a281ed42b6f13c4 100644 (file)
@@ -199,30 +199,6 @@ boxes this will leave gaps in the sequence of device names. ip2mkdev uses
 Linux tty naming conventions: ttyF0 - ttyF255 for normal devices, and
 cuf0 - cuf255 for callout devices.
 
-If you are using devfs, existing devices are automatically created within
-the devfs name space.  Normal devices will be tts/F0 - tts/F255 and callout
-devices will be cua/F0 - cua/F255.  With devfs installed, ip2mkdev will
-create symbolic links in /dev from the old conventional names to the newer
-devfs names as follows:
-
-       /dev/ip2ipl[n]  -> /dev/ip2/ipl[n]      n = 0 - 3
-       /dev/ip2stat[n] -> /dev/ip2/stat[n]     n = 0 - 3
-       /dev/ttyF[n]    -> /dev/tts/F[n]        n = 0 - 255
-       /dev/cuf[n]     -> /dev/cua/F[n]        n = 0 - 255
-
-Only devices for existing ports and boards will be created.
-
-IMPORTANT NOTE:  The naming convention used for devfs by this driver
-was changed from 1.2.12 to 1.2.13.  The old naming convention was to
-use ttf/%d for the tty device and cuf/%d for the cua device.  That
-has been changed to conform to an agreed-upon standard of placing
-all the tty devices under tts.  The device names are now tts/F%d for
-the tty device and cua/F%d for the cua devices.  If you were using
-the older devfs names, you must update for the newer convention.
-
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
-
 
 4. USING THE DRIVERS
 
@@ -256,57 +232,15 @@ cut out and run as "ip2mkdev" to create the necessary device files.  To
 use the ip2mkdev script, you must have procfs enabled and the proc file
 system mounted on /proc.
 
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
-
-
-6. DEVFS
-
-DEVFS is the DEVice File System available as an add on package for the
-2.2.x kernels and available as a configuration option in 2.3.46 and higher.
-Devfs allows for the automatic creation and management of device names
-under control of the device drivers themselves.  The Devfs namespace is
-hierarchical and reduces the clutter present in the normal flat /dev
-namespace.  Devfs names and conventional device names may be intermixed.
-A userspace daemon, devfsd, exists to allow for automatic creation and
-management of symbolic links from the devfs name space to the conventional
-names.  More details on devfs can be found on the DEVFS home site at
-<http://www.atnf.csiro.au/~rgooch/linux/> or in the file kernel
-documentation files, .../linux/Documentation/filesystems/devfs/README.
-
-If you are using devfs, existing devices are automatically created within
-the devfs name space.  Normal devices will be tts/F0 - tts/F255 and callout
-devices will be cua/F0 - cua/F255.  With devfs installed, ip2mkdev will
-create symbolic links in /dev from the old conventional names to the newer
-devfs names as follows:
-
-       /dev/ip2ipl[n]  -> /dev/ip2/ipl[n]      n = 0 - 3
-       /dev/ip2stat[n] -> /dev/ip2/stat[n]     n = 0 - 3
-       /dev/ttyF[n]    -> /dev/tts/F[n]        n = 0 - 255
-       /dev/cuf[n]     -> /dev/cua/F[n]        n = 0 - 255
-
-Only devices for existing ports and boards will be created.
-
-IMPORTANT NOTE:  The naming convention used for devfs by this driver
-was changed from 1.2.12 to 1.2.13.  The old naming convention was to
-use ttf/%d for the tty device and cuf/%d for the cua device.  That
-has been changed to conform to an agreed-upon standard of placing
-all the tty devices under tts.  The device names are now tts/F%d for
-the tty device and cua/F%d for the cua devices.  If you were using
-the older devfs names, you must update for the newer convention.
-
-You do not need to run ip2mkdev if you are using devfs and only want to
-use the devfs native device names.
 
-7. NOTES
+6. NOTES
 
 This is a release version of the driver, but it is impossible to test it
 in all configurations of Linux. If there is any anomalous behaviour that 
 does not match the standard serial port's behaviour please let us know.
 
 
-8. ip2mkdev shell script
+7. ip2mkdev shell script
 
 Previously, this script was simply attached here.  It is now attached as a
 shar archive to make it easier to extract the script from the documentation.
index 6a82948ff4bd59adb26b08e305339b4452f79edc..53d62c1e1c94f68531756d20c80e50c48aa718b3 100644 (file)
@@ -1,5 +1,5 @@
 
-     CPU frequency and voltage scaling statictics in the Linux(TM) kernel
+     CPU frequency and voltage scaling statistics in the Linux(TM) kernel
 
 
              L i n u x    c p u f r e q - s t a t s   d r i v e r
@@ -18,8 +18,8 @@ Contents
 1. Introduction
 
 cpufreq-stats is a driver that provices CPU frequency statistics for each CPU.
-This statistics is provided in /sysfs as a bunch of read_only interfaces. This
-interface (when configured) will appear in a seperate directory under cpufreq
+These statistics are provided in /sysfs as a bunch of read_only interfaces. This
+interface (when configured) will appear in a separate directory under cpufreq
 in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU.
 Various statistics will form read_only files under this directory.
 
@@ -53,7 +53,7 @@ drwxr-xr-x  3 root root    0 May 14 15:58 ..
 This gives the amount of time spent in each of the frequencies supported by
 this CPU. The cat output will have "<frequency> <time>" pair in each line, which
 will mean this CPU spent <time> usertime units of time at <frequency>. Output
-will have one line for each of the supported freuencies. usertime units here 
+will have one line for each of the supported frequencies. usertime units here 
 is 10mS (similar to other time exported in /proc).
 
 --------------------------------------------------------------------------------
@@ -115,7 +115,7 @@ basic statistics which includes time_in_state and total_trans.
 
 "CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS)
 provides fine grained cpufreq stats by trans_table. The reason for having a
-seperate config option for trans_table is:
+separate config option for trans_table is:
 - trans_table goes against the traditional /sysfs rule of one value per
   interface. It provides a whole bunch of value in a 2 dimensional matrix
   form.
index f4b8dc4237e6a83b6f0cf44cfc3861f924baec10..6a9c55bd556baf199a7f0607d47860c4e86987dd 100644 (file)
@@ -57,7 +57,7 @@ selected for each specific use.
 
 Basically, it's the following flow graph:
 
-CPU can be set to switch independetly   |         CPU can only be set
+CPU can be set to switch independently  |         CPU can only be set
       within specific "limits"          |       to specific frequencies
 
                                  "CPUfreq policy"
@@ -109,7 +109,7 @@ directory.
 2.4 Ondemand
 ------------
 
-The CPUfreq govenor "ondemand" sets the CPU depending on the
+The CPUfreq governor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
 switch the frequency very quickly.  There are a number of sysfs file
 accessible parameters:
@@ -137,11 +137,11 @@ have to be made in a row before the CPU frequency is actually lower.
 If set to '1' then the frequency decreases as quickly as it increases,
 if set to '2' it decreases at half the rate of the increase.
 
-ignore_nice_load: this parameter takes a value of '0' or '1', when set
-to '0' (its default) then all processes are counted towards towards the
-'cpu utilisation' value.   When set to '1' then processes that are
+ignore_nice_load: this parameter takes a value of '0' or '1'. When
+set to '0' (its default), all processes are counted towards the
+'cpu utilisation' value.  When set to '1', the processes that are
 run with a 'nice' value will not count (and thus be ignored) in the
-overal usage calculation.  This is useful if you are running a CPU
+overall usage calculation.  This is useful if you are running a CPU
 intensive calculation on your laptop that you do not care how long it
 takes to complete as you can 'nice' it and prevent it from taking part
 in the deciding process of whether to increase your CPU frequency.
index 2b28e9ec4e3a2437d8108dc5aee3976a281b9903..b61cb9564023b6dc878246fac760280c670d5ccf 100644 (file)
@@ -26,7 +26,7 @@ The type of **_id is int.
 The type of siblings is cpumask_t.
 
 To be consistent on all architectures, the 4 attributes should have
-deafult values if their values are unavailable. Below is the rule.
+default values if their values are unavailable. Below is the rule.
 1) physical_package_id: If cpu has no physical package id, -1 is the
 default value.
 2) core_id: If cpu doesn't support multi-core, its core id is 0.
index 941343a7a265e91e379cd52b267519e322dedf25..2c0d631de0cf857d5f65c3a712f331fab84d0144 100644 (file)
@@ -4,7 +4,7 @@ for updating BIOS images on Dell servers and desktops.
 
 Scope:
 This document discusses the functionality of the rbu driver only.
-It does not cover the support needed from aplications to enable the BIOS to
+It does not cover the support needed from applications to enable the BIOS to
 update itself with the image downloaded in to the memory.
 
 Overview:
@@ -16,8 +16,8 @@ OpenManage and Dell Update packages (DUP).
 Libsmbios can also be used to update BIOS on Dell systems go to
 http://linux.dell.com/libsmbios/ for details.
 
-Dell_RBU driver supports BIOS update using the monilothic image and packetized
-image methods. In case of moniolithic the driver allocates a contiguous chunk
+Dell_RBU driver supports BIOS update using the monolithic image and packetized
+image methods. In case of monolithic the driver allocates a contiguous chunk
 of physical pages having the BIOS image. In case of packetized the app
 using the driver breaks the image in to packets of fixed sizes and the driver
 would place each packet in contiguous physical memory. The driver also
@@ -41,7 +41,7 @@ The driver supports two types of update mechanism; monolithic and packetized.
 These update mechanism depends upon the BIOS currently running on the system.
 Most of the Dell systems support a monolithic update where the BIOS image is
 copied to a single contiguous block of physical memory.
-In case of packet mechanism the single memory can be broken in smaller chuks
+In case of packet mechanism the single memory can be broken in smaller chunks
 of contiguous memory and the BIOS image is scattered in these packets.
 
 By default the driver uses monolithic memory for the update type. This can be
@@ -52,11 +52,11 @@ echo packet > /sys/devices/platform/dell_rbu/image_type
 In packet update mode the packet size has to be given before any packets can
 be downloaded. It is done as below
 echo XXXX > /sys/devices/platform/dell_rbu/packet_size
-In the packet update mechanism, the user neesd to create a new file having
+In the packet update mechanism, the user needs to create a new file having
 packets of data arranged back to back. It can be done as follows
 The user creates packets header, gets the chunk of the BIOS image and
-placs it next to the packetheader; now, the packetheader + BIOS image chunk
-added to geather should match the specified packet_size. This makes one
+places it next to the packetheader; now, the packetheader + BIOS image chunk
+added together should match the specified packet_size. This makes one
 packet, the user needs to create more such packets out of the entire BIOS
 image file and then arrange all these packets back to back in to one single
 file.
@@ -93,8 +93,8 @@ read back the image downloaded.
 NOTE:
 This driver requires a patch for firmware_class.c which has the modified
 request_firmware_nowait function.
-Also after updating the BIOS image an user mdoe application neeeds to execute
-code which message the BIOS update request to the BIOS. So on the next reboot
-the BIOS knows about the new image downloaded and it updates it self.
-Also don't unload the rbu drive if the image has to be updated.
+Also after updating the BIOS image a user mode application needs to execute
+code which sends the BIOS update request to the BIOS. So on the next reboot
+the BIOS knows about the new image downloaded and it updates itself.
+Also don't unload the rbu driver if the image has to be updated.
 
index addc67b1d770e26fd0dee02613866a40735f01b1..28c4f79662c2a84b05361d02f429b075e346380d 100644 (file)
@@ -2005,7 +2005,7 @@ Your cooperation is appreciated.
 116 char       Advanced Linux Sound Driver (ALSA)
 
 116 block       MicroMemory battery backed RAM adapter (NVRAM)
-                Supports 16 boards, 15 paritions each.
+                Supports 16 boards, 15 partitions each.
                 Requested by neilb at cse.unsw.edu.au.
 
                 0 = /dev/umem/d0      Whole of first board
@@ -3094,7 +3094,7 @@ Your cooperation is appreciated.
                This major is reserved to assist the expansion to a
                larger number space.  No device nodes with this major
                should ever be created on the filesystem.
-               (This is probaly not true anymore, but I'll leave it
+               (This is probably not true anymore, but I'll leave it
                for now /Torben)
 
 ---LARGE MAJORS!!!!!---
@@ -3205,7 +3205,7 @@ for a session; this includes virtual consoles, serial ports, and
 pseudoterminals (PTYs).
 
 All terminal devices share a common set of capabilities known as line
-diciplines; these include the common terminal line dicipline as well
+disciplines; these include the common terminal line discipline as well
 as SLIP and PPP modes.
 
 All terminal devices are named similarly; this section explains the
@@ -3285,7 +3285,7 @@ port TTY, for which no alternate device would exist.
        Pseudoterminals (PTYs)
 
 Pseudoterminals, or PTYs, are used to create login sessions or provide
-other capabilities requiring a TTY line dicipline (including SLIP or
+other capabilities requiring a TTY line discipline (including SLIP or
 PPP capability) to arbitrary data-generation processes.         Each PTY has
 a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named
 /dev/tty[p-za-e][0-9a-f].  The kernel arbitrates the use of PTYs by
index 2d1d893a5e5d7e8ef01b4fdce6a3aac37b4a4482..548505f14aa481fd906967272f1da6b6b7da3259 100644 (file)
@@ -12,7 +12,7 @@ device. The following device classes have been identified:
 
 Each device class defines a set of semantics and a programming interface
 that devices of that class adhere to. Device drivers are the
-implemention of that programming interface for a particular device on
+implementation of that programming interface for a particular device on
 a particular bus. 
 
 Device classes are agnostic with respect to what bus a device resides
index 59806c9761f7bbbd2c6c03e08fb95bf57f342b7d..82132169d47a837fc55ea9d53555abc29b2c7b5d 100644 (file)
@@ -178,7 +178,7 @@ the driver to that device.
 
 A driver's probe() may return a negative errno value to indicate that
 the driver did not bind to this device, in which case it should have
-released all reasources it allocated.
+released all resources it allocated.
 
        int     (*remove)       (struct device * dev);
 
index 2050c9ffc629da6a3079816551cdbc88f43deb49..07236ed968da5633a845161ec334fd6b0f332a91 100644 (file)
@@ -57,7 +57,7 @@ the two.
 
 The PCI bus layer freely accesses the fields of struct device. It knows about
 the structure of struct pci_dev, and it should know the structure of struct
-device. Individual PCI device drivers that have been converted the the current
+device. Individual PCI device drivers that have been converted to the current
 driver model generally do not and should not touch the fields of struct device,
 unless there is a strong compelling reason to do so.
 
index 8bab8461a4af177d6548858f87f3b79aa8807267..e44c009ac6c5ef8dcf7cd5d295631b17ecc90e4f 100644 (file)
@@ -45,9 +45,9 @@ Assumptions and Introduction
    by  circuitry on the card and is often presented uncompressed.
    For  a PAL TV signal encoded at a resolution of 768x576 24-bit
    color pixels over 25 frames per second - a fair amount of data
-   is  generated and must be proceesed by the PC before it can be
+   is  generated and must be processed by the PC before it can be
    displayed  on the video monitor screen. Some Analogue TV cards
-   for  PC's  have  onboard  MPEG2  encoders which permit the raw
+   for  PCs  have  onboard  MPEG2  encoders  which permit the raw
    digital  data  stream  to be presented to the PC in an encoded
    and  compressed  form  -  similar  to the form that is used in
    Digital TV.
index 9e10092440e1d61836481300004740ee1f89d984..ca58e339d85fe2e1fa036e89719b40c462d3d0d6 100644 (file)
@@ -5,7 +5,7 @@ Hardware supported by the linuxtv.org DVB drivers
   frontends (i.e. tuner / demodulator units) used, usually without
   changing the product name, revision number or specs. Some cards
   are also available in versions with different frontends for
-  DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed seperately.
+  DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed separately.
 
   Note 1: There is no guarantee that every frontend driver works
   out of the box with every card, because of different wiring.
index 95f0e73b2135a10463476e0fbe789dba62eb2ef5..531239b2908210dd78a26809e23b570a8be1ad53 100644 (file)
@@ -32,7 +32,7 @@ This application requires the following to function properly as of now.
          descrambler to function,
          eg: $ ca_zap channels.conf "TMC"
 
-       (d) Hopeflly Enjoy your favourite subscribed channel as you do with
+       (d) Hopefully enjoy your favourite subscribed channel as you do with
          a FTA card.
 
 (3) Currently ca_zap, and dst_test, both are meant for demonstration
@@ -65,7 +65,7 @@ Modules that have been tested by this driver at present are
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 With the High Level CI approach any new card with almost any random
 architecture can be implemented with this style, the definitions
-insidethe switch statement can be easily adapted for any card, thereby
+inside the switch statement can be easily adapted for any card, thereby
 eliminating the need for any additional ioctls.
 
 The disadvantage is that the driver/hardware has to manage the rest. For
index a42132d60dc8889f25aea6d939e25ce0eb103128..dbcedf5833eea25ce641caec237aae6ddd5cbd09 100644 (file)
@@ -5,7 +5,7 @@ Some very frequently asked questions about linuxtv-dvb
        It's not a bug, it's a feature. Because the frontends have
        significant power requirements (and hence get very hot), they
        are powered down if they are unused (i.e. if the frontend device
-       is closed). The dvb-core.o module paramter "dvb_shutdown_timeout"
+       is closed). The dvb-core.o module parameter "dvb_shutdown_timeout"
        allow you to change the timeout (default 5 seconds). Setting the
        timeout to 0 disables the timeout feature.
 
@@ -138,7 +138,7 @@ Some very frequently asked questions about linuxtv-dvb
 
        - v4l2-common: common functions for Video4Linux-2 drivers
 
-       - v4l1-compat: backward compatiblity layer for Video4Linux-1 legacy
+       - v4l1-compat: backward compatibility layer for Video4Linux-1 legacy
          applications
 
        - dvb-core: DVB core module. This provides you with the
@@ -153,7 +153,7 @@ Some very frequently asked questions about linuxtv-dvb
        - video-buf: capture helper module for the saa7146_vv driver. This
          one is responsible to handle capture buffers.
 
-       - dvb-ttpci: The main driver for AV7110 based, full-featued
+       - dvb-ttpci: The main driver for AV7110 based, full-featured
          DVB-S/C/T cards
 
 eof
diff --git a/Documentation/ecryptfs.txt b/Documentation/ecryptfs.txt
new file mode 100644 (file)
index 0000000..01d8a08
--- /dev/null
@@ -0,0 +1,77 @@
+eCryptfs: A stacked cryptographic filesystem for Linux
+
+eCryptfs is free software. Please see the file COPYING for details.
+For documentation, please see the files in the doc/ subdirectory.  For
+building and installation instructions please see the INSTALL file.
+
+Maintainer: Phillip Hellewell
+Lead developer: Michael A. Halcrow <mhalcrow@us.ibm.com>
+Developers: Michael C. Thompson
+            Kent Yoder
+Web Site: http://ecryptfs.sf.net
+
+This software is currently undergoing development. Make sure to
+maintain a backup copy of any data you write into eCryptfs.
+
+eCryptfs requires the userspace tools downloadable from the
+SourceForge site:
+
+http://sourceforge.net/projects/ecryptfs/
+
+Userspace requirements include:
+ - David Howells' userspace keyring headers and libraries (version
+   1.0 or higher), obtainable from
+   http://people.redhat.com/~dhowells/keyutils/
+ - Libgcrypt
+
+
+NOTES
+
+In the beta/experimental releases of eCryptfs, when you upgrade
+eCryptfs, you should copy the files to an unencrypted location and
+then copy the files back into the new eCryptfs mount to migrate the
+files.
+
+
+MOUNT-WIDE PASSPHRASE
+
+Create a new directory into which eCryptfs will write its encrypted
+files (i.e., /root/crypt).  Then, create the mount point directory
+(i.e., /mnt/crypt).  Now it's time to mount eCryptfs:
+
+mount -t ecryptfs /root/crypt /mnt/crypt
+
+You should be prompted for a passphrase and a salt (the salt may be
+blank).
+
+Try writing a new file:
+
+echo "Hello, World" > /mnt/crypt/hello.txt
+
+The operation will complete.  Notice that there is a new file in
+/root/crypt that is at least 12288 bytes in size (depending on your
+host page size).  This is the encrypted underlying file for what you
+just wrote.  To test reading, from start to finish, you need to clear
+the user session keyring:
+
+keyctl clear @u
+
+Then umount /mnt/crypt and mount again per the instructions given
+above.
+
+cat /mnt/crypt/hello.txt
+
+
+NOTES
+
+eCryptfs version 0.1 should only be mounted on (1) empty directories
+or (2) directories containing files only created by eCryptfs. If you
+mount a directory that has pre-existing files not created by eCryptfs,
+then behavior is undefined. Do not run eCryptfs in higher verbosity
+levels unless you are doing so for the sole purpose of debugging or
+development, since secret values will be written out to the system log
+in that case.
+
+
+Mike Halcrow
+mhalcrow@us.ibm.com
index 8c8388da868a43127052e5672894bad520452f7f..6a099edadd622f625e2606c9402916a227accf4e 100644 (file)
@@ -18,7 +18,7 @@ The EISA infrastructure is made up of three parts :
 
     - The bus code implements most of the generic code. It is shared
     among all the architectures that the EISA code runs on. It
-    implements bus probing (detecting EISA cards avaible on the bus),
+    implements bus probing (detecting EISA cards available on the bus),
     allocates I/O resources, allows fancy naming through sysfs, and
     offers interfaces for driver to register.
 
@@ -84,7 +84,7 @@ struct eisa_driver {
 
 id_table       : an array of NULL terminated EISA id strings,
                  followed by an empty string. Each string can
-                 optionnaly be paired with a driver-dependant value
+                 optionally be paired with a driver-dependant value
                  (driver_data).
 
 driver         : a generic driver, such as described in
index 3cb39ade290eae9d3e3046cfb04fe340e601d5b9..2d5aded64247343e1cfa13ded99c3a1e0204517a 100644 (file)
@@ -10,7 +10,7 @@ int verify_area(int type, const void * addr, unsigned long size)
 function (which has since been replaced by access_ok()).
 
 This function verified that the memory area starting at address 
-addr and of size size was accessible for the operation specified 
+'addr' and of size 'size' was accessible for the operation specified
 in type (read or write). To do this, verify_read had to look up the 
 virtual memory area (vma) that contained the address addr. In the 
 normal case (correctly working program), this test was successful. 
index f373df12ed4ce9bd236454495529387509359801..99ea58e65eff66ff326590b8657032f234fd7f9f 100644 (file)
@@ -163,7 +163,7 @@ from the console layer before unloading the driver.  The VGA driver cannot be
 unloaded if it is still bound to the console layer. (See
 Documentation/console/console.txt for more information).
 
-This is more complicated in the case of the the framebuffer console (fbcon),
+This is more complicated in the case of the framebuffer console (fbcon),
 because fbcon is an intermediate layer between the console and the drivers:
 
 console ---> fbcon ---> fbdev drivers ---> hardware
index 3b50c517a08d624e1e24fe85a62fe98075683c4d..2e68e503e72f188be2e71b6ca4a52f7a62a01594 100644 (file)
@@ -72,7 +72,7 @@ information. Additionally, "modinfo sisfb" gives an overview over all
 supported options including some explanation.
 
 The desired display mode can be specified using the keyword "mode" with
-a parameter in one of the follwing formats:
+a parameter in one of the following formats:
   - XxYxDepth or
   - XxY-Depth or
   - XxY-Depth@Rate or
index 628d7ffa876968dc52333cf5314b2f056e98d5b0..df27f5bf15dbc4cef4e0285085b4adc2709b279a 100644 (file)
@@ -48,12 +48,12 @@ Module Usage
 
        Module insertion:
        # insmod sstfb.o
-         you should see some strange output frome the board: 
+         you should see some strange output from the board: 
          a big blue square, a green and a red small squares and a vertical
-         white rectangle. why ? the function's name is self explanatory :
+         white rectangle. why? the function's name is self-explanatory:
          "sstfb_test()"...
          (if you don't have a second monitor, you'll have to plug your monitor
-         directely to the 2D videocard to see what you're typing)
+         directly to the 2D videocard to see what you're typing)
        # con2fb /dev/fbx /dev/ttyx
          bind a tty to the new frame buffer. if you already have a frame
          buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
@@ -72,12 +72,12 @@ Module Usage
 
 Kernel/Modules Options
 
-       You can pass some otions to sstfb module, and via the kernel command
-       line when the driver is compiled in :
+       You can pass some options to the sstfb module, and via the kernel 
+       command line when the driver is compiled in:
        for module : insmod sstfb.o option1=value1 option2=value2 ...
        in kernel :  video=sstfb:option1,option2:value2,option3 ...
        
-       sstfb supports the folowing options :
+       sstfb supports the following options :
 
 Module         Kernel          Description
 
@@ -95,11 +95,11 @@ inverse=1   inverse         Supposed to enable inverse console.
 
 clipping=1     clipping        Enable or disable clipping.
 clipping=0     noclipping      With clipping enabled, all offscreen
-                               reads and writes are disgarded.
+                               reads and writes are discarded.
                                Default: enable clipping.
 
 gfxclk=x       gfxclk:x        Force graphic clock frequency (in MHz).
-                               Be carefull with this option, it may be
+                               Be careful with this option, it may be
                                DANGEROUS.
                                Default: auto 
                                        50Mhz for Voodoo 1,
@@ -137,23 +137,23 @@ Bugs
        - The driver is 16 bpp only, 24/32 won't work.
        - The driver is not your_favorite_toy-safe. this includes SMP...
           [Actually from inspection it seems to be safe - Alan]
-       - when using XFree86 FBdev (X over fbdev) you may see strange color
+       - When using XFree86 FBdev (X over fbdev) you may see strange color
        patterns at the border of your windows (the pixels lose the lowest
-       byte -> basicaly the blue component nd some of the green) . I'm unable
+       byte -> basically the blue component and some of the green). I'm unable
        to reproduce this with XFree86-3.3, but one of the testers has this
-       problem with XFree86-4. apparently recent Xfree86-4.x solve this
+       problem with XFree86-4. Apparently recent Xfree86-4.x solve this
        problem.
        - I didn't really test changing the palette, so you may find some weird
        things when playing with that.
-       - Sometimes the driver will not recognise the DAC , and the
-        initialisation will fail. this is specificaly true for
-       voodoo 2 boards , but it should be solved in recent versions. please
-       contact me .
-       - the 24/32 is not likely to work anytime soon , knowing that the
-       hardware does ... unusual thigs in 24/32 bpp
-       - When used with anther video board, current limitations of linux
-       console subsystem can cause some troubles, specificaly, you should
-       disable software scrollback , as it can oops badly ...
+       - Sometimes the driver will not recognise the DAC, and the
+        initialisation will fail. This is specifically true for
+       voodoo 2 boards, but it should be solved in recent versions. Please
+       contact me.
+       - The 24/32 is not likely to work anytime soon, knowing that the
+       hardware does ... unusual things in 24/32 bpp.
+       - When used with another video board, current limitations of the linux
+       console subsystem can cause some troubles, specifically, you should
+       disable software scrollback, as it can oops badly ...
 
 Todo
 
@@ -161,7 +161,7 @@ Todo
        - Buy more coffee.
        - test/port to other arch.
        - try to add panning using tweeks with front and back buffer .
-       - try to implement accel on voodoo2 , this board can actualy do a 
+       - try to implement accel on voodoo2, this board can actually do a 
          lot in 2D even if it was sold as a 3D only board ...
 
 ghoz.
index 2e410f5aa750b5ed7ea4f35e36ed8edbfe23b017..24f3c63b301710ba461e04e9fc353c9f4a5eabcd 100644 (file)
@@ -29,14 +29,6 @@ Who: Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  drivers that were depending on OBSOLETE_OSS_DRIVER
-        (config options already removed)
-When:  before 2.6.19
-Why:   OSS drivers with ALSA replacements
-Who:   Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:  raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 When:  November 2006
 Why:   Deprecated in favour of the new ioctl-based rawiso interface, which is
@@ -184,7 +176,7 @@ Who:        Greg Kroah-Hartman <gregkh@suse.de>
 ---------------------------
 
 What:  USB driver API moves to EXPORT_SYMBOL_GPL
-When:  Febuary 2008
+When:  February 2008
 Files: include/linux/usb.h, drivers/usb/core/driver.c
 Why:   The USB subsystem has changed a lot over time, and it has been
        possible to create userspace USB drivers using usbfs/libusb/gadgetfs
index 16dec61d7671507d6ec25115ec16b376aee8f18c..3c384c0cf86e0a6484e121fdc817c4307dcbce21 100644 (file)
@@ -26,8 +26,6 @@ cramfs.txt
        - info on the cram filesystem for small storage (ROMs etc).
 dentry-locking.txt
        - info on the RCU-based dcache locking model.
-devfs/
-       - directory containing devfs documentation.
 directory-locking
        - info about the locking scheme used for directory operations.
 dlmfs.txt
index 877a7b1d46ec2a9f48a6a06f4cbbdf6051f03262..67391a15949ab0af32ce313df370a8a99b0ae647 100644 (file)
@@ -7,7 +7,7 @@ WARNING
 Make sure you understand that this is alpha software.  This means that the
 implementation is neither complete nor well-tested. 
 
-I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+I DISCLAIM ALL RESPONSIBILITY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
 
 LICENSE
 =====
@@ -22,7 +22,7 @@ He has been working on the code since Aug 13, 2001. See the changelog for
 details.
 
 Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
-His orriginal code can still be found at:
+His original code can still be found at:
 <http://hp.vector.co.jp/authors/VA008030/bfs/>
 Does anyone know of a more current email address for Makoto? He doesn't
 respond to the address given above...
@@ -39,7 +39,7 @@ Which is it, BFS or BEFS?
 ================
 Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
 But Unixware Boot Filesystem is called bfs, too. And they are already in
-the kernel. Because of this nameing conflict, on Linux the BeOS
+the kernel. Because of this naming conflict, on Linux the BeOS
 filesystem is called befs.
 
 HOW TO INSTALL
@@ -57,7 +57,7 @@ if the patching step fails (i.e. there are rejected hunks), you can try to
 figure it out yourself (it shouldn't be hard), or mail the maintainer 
 (Will Dyson <will_dyson@pobox.com>) for help.
 
-step 2.  Configuretion & make kernel
+step 2.  Configuration & make kernel
 
 The linux kernel has many compile-time options. Most of them are beyond the
 scope of this document. I suggest the Kernel-HOWTO document as a good general
index c4ff96b7c4e06279fed43e9a3ff548b4cb90997e..c3a7afb5eabf337a8dc272220070c7e96bbc7d8f 100644 (file)
@@ -1,5 +1,5 @@
 
-configfs - Userspace-driven kernel object configuation.
+configfs - Userspace-driven kernel object configuration.
 
 Joel Becker <joel.becker@oracle.com>
 
@@ -254,7 +254,7 @@ using the group _init() functions on the group.
 
 Finally, when userspace calls rmdir(2) on the item or group,
 ct_group_ops->drop_item() is called.  As a config_group is also a
-config_item, it is not necessary for a seperate drop_group() method.
+config_item, it is not necessary for a separate drop_group() method.
 The subsystem must config_item_put() the reference that was initialized
 upon item allocation.  If a subsystem has no work to do, it may omit
 the ct_group_ops->drop_item() method, and configfs will call
@@ -406,7 +406,7 @@ that condition is met.
 
 Far better would be an explicit action notifying the subsystem that the
 config_item is ready to go.  More importantly, an explicit action allows
-the subsystem to provide feedback as to whether the attibutes are
+the subsystem to provide feedback as to whether the attributes are
 initialized in a way that makes sense.  configfs provides this as
 committable items.
 
@@ -422,7 +422,7 @@ support mkdir(2) or rmdir(2) either.  It only allows rename(2).  The
 "pending" directory does allow mkdir(2) and rmdir(2).  An item is
 created in the "pending" directory.  Its attributes can be modified at
 will.  Userspace commits the item by renaming it into the "live"
-directory.  At this point, the subsystem recieves the ->commit_item()
+directory.  At this point, the subsystem receives the ->commit_item()
 callback.  If all required attributes are filled to satisfaction, the
 method returns zero and the item is moved to the "live" directory.
 
index 34380d4fbce399e61e118ec79dc4cb70c4a2ce44..d7099a9266fb3e4703ea471b2a3bb08d69f75348 100644 (file)
@@ -82,7 +82,7 @@ own descendent.  Moreover, there is exactly one cross-directory rename
 
        Consider the object blocking the cross-directory rename.  One
 of its descendents is locked by cross-directory rename (otherwise we
-would again have an infinite set of of contended objects).  But that
+would again have an infinite set of contended objects).  But that
 means that cross-directory rename is taking locks out of order.  Due
 to (2) the order hadn't changed since we had acquired filesystem lock.
 But locking rules for cross-directory rename guarantee that we do not
index 9afab845a906967acdc312df918e058015c33bed..c50bbb2d52b463a20165d05d5a0eeb5049c9a9a3 100644 (file)
@@ -68,7 +68,7 @@ request for an already acquired lock will not generate another DLM
 call. Userspace programs are assumed to handle their own local
 locking.
 
-Two levels of locks are supported - Shared Read, and Exlcusive.
+Two levels of locks are supported - Shared Read, and Exclusive.
 Also supported is a Trylock operation.
 
 For information on the libo2dlm interface, please see o2dlm.h,
index 3dd2872416a1e338062c722da8145539153c21f4..4333e836c4951459d9145213938bbca78644d63d 100644 (file)
@@ -205,7 +205,7 @@ Reserved Space
 
 In ext2, there is a mechanism for reserving a certain number of blocks
 for a particular user (normally the super-user).  This is intended to
-allow for the system to continue functioning even if non-priveleged users
+allow for the system to continue functioning even if non-privileged users
 fill up all the space available to them (this is independent of filesystem
 quotas).  It also keeps the filesystem from filling up entirely which
 helps combat fragmentation.
index 8c206f4e02508b1a01b61561afa8039a475d8830..133e213ebb721912a79c2c6621ef30050941ce6e 100644 (file)
@@ -55,7 +55,7 @@ the fdtable structure -
 2. Reading of the fdtable as described above must be protected
    by rcu_read_lock()/rcu_read_unlock().
 
-3. For any update to the the fd table, files->file_lock must
+3. For any update to the fd table, files->file_lock must
    be held.
 
 4. To look up the file structure given an fd, a reader
index 638cbd3d2b00054e31ece5a580366a071827a25c..35f105b29e3e26bb4201049f663062989b4693b8 100644 (file)
@@ -13,7 +13,7 @@ Table of contents
 - Using NTFS volume and stripe sets
   - The Device-Mapper driver
   - The Software RAID / MD driver
-  - Limitiations when using the MD driver
+  - Limitations when using the MD driver
 - ChangeLog
 
 
@@ -43,7 +43,7 @@ There is plenty of additional information on the linux-ntfs web site
 at http://linux-ntfs.sourceforge.net/
 
 The web site has a lot of additional information, such as a comprehensive
-FAQ, documentation on the NTFS on-disk format, informaiton on the Linux-NTFS
+FAQ, documentation on the NTFS on-disk format, information on the Linux-NTFS
 userspace utilities, etc.
 
 
@@ -383,14 +383,14 @@ Software RAID / MD driver.  For which you need to set up your /etc/raidtab
 appropriately (see man 5 raidtab).
 
 Linear volume sets, i.e. linear raid, as well as stripe sets, i.e. raid level
-0, have been tested and work fine (though see section "Limitiations when using
+0, have been tested and work fine (though see section "Limitations when using
 the MD driver with NTFS volumes" especially if you want to use linear raid).
 Even though untested, there is no reason why mirrors, i.e. raid level 1, and
 stripes with parity, i.e. raid level 5, should not work, too.
 
 You have to use the "persistent-superblock 0" option for each raid-disk in the
 NTFS volume/stripe you are configuring in /etc/raidtab as the persistent
-superblock used by the MD driver would damange the NTFS volume.
+superblock used by the MD driver would damage the NTFS volume.
 
 Windows by default uses a stripe chunk size of 64k, so you probably want the
 "chunk-size 64k" option for each raid-disk, too.
@@ -435,7 +435,7 @@ setup correctly to avoid the possibility of causing damage to the data on the
 ntfs volume.
 
 
-Limitiations when using the Software RAID / MD driver
+Limitations when using the Software RAID / MD driver
 -----------------------------------------------------
 
 Using the md driver will not work properly if any of your NTFS partitions have
index 7240ee7515decf7b8d5205a18e43b891ddba2f9a..3355e6920105014bda194eb3a1c5360f37a33916 100644 (file)
@@ -410,7 +410,7 @@ VmallocChunk:   111088 kB
               this memory, making it slower to access than lowmem.
     LowTotal:
      LowFree: Lowmem is memory which can be used for everything that
-              highmem can be used for, but it is also availble for the
+              highmem can be used for, but it is also available for the
               kernel's use for its own data structures.  Among many
               other things, it is where everything from the Slab is
               allocated.  Bad things happen when you're out of lowmem.
@@ -1255,7 +1255,7 @@ to allocate (but not use) more memory than is actually available.
                address space are refused. Used for a typical system. It
                ensures a seriously wild allocation fails while allowing
                overcommit to reduce swap usage.  root is allowed to
-               allocate slighly more memory in this mode. This is the
+               allocate slightly more memory in this mode. This is the
                default.
 
 1      -       Always overcommit. Appropriate for some scientific
@@ -1588,7 +1588,7 @@ Enable the  strict  RFC793 interpretation of the TCP urgent pointer field. The
 default is  to  use  the  BSD  compatible interpretation of the urgent pointer
 pointing to the first byte after the urgent data. The RFC793 interpretation is
 to have  it  point  to  the last byte of urgent data. Enabling this option may
-lead to interoperatibility problems. Disabled by default.
+lead to interoperability problems. Disabled by default.
 
 tcp_syncookies
 --------------
@@ -1733,7 +1733,7 @@ error_burst and error_cost
 
 These  parameters  are used to limit how many ICMP destination unreachable to 
 send  from  the  host  in question. ICMP destination unreachable messages are 
-sent  when  we can not reach the next hop, while trying to transmit a packet. 
+sent  when  we  cannot reach  the next hop while trying to transmit a packet. 
 It  will also print some error messages to kernel logs if someone is ignoring 
 our   ICMP  redirects.  The  higher  the  error_cost  factor  is,  the  fewer 
 destination  unreachable  and error messages will be let through. Error_burst 
@@ -1857,7 +1857,7 @@ proxy_qlen
 
 Maximum queue length of the delayed proxy arp timer. (see proxy_delay).
 
-app_solcit
+app_solicit
 ----------
 
 Determines the  number of requests to send to the user level ARP daemon. Use 0
index 8edc3952eff466b943caf61080b5735f899ea179..982645a1981de148771c844c41e7affa6373b3aa 100644 (file)
@@ -84,7 +84,7 @@ FILES
    /ibox
        The  second  SPU  to CPU communication mailbox. This file is similar to
        the first mailbox file, but can be read in blocking I/O mode,  and  the
-       poll  familiy of system calls can be used to wait for it.  The possible
+       poll  family of system calls can be used to wait for it.  The  possible
        operations on an open ibox file are:
 
        read(2)
@@ -105,7 +105,7 @@ FILES
 
 
    /wbox
-       The CPU to SPU communation mailbox. It is write-only can can be written
+       The CPU to SPU communation mailbox. It is write-only and can be written
        in  units  of  32  bits. If the mailbox is full, write() will block and
        poll can be used to wait for it becoming  empty  again.   The  possible
        operations  on  an open wbox file are: write(2) If a count smaller than
@@ -359,7 +359,7 @@ ERRORS
        EFAULT npc is not a valid pointer or status is neither NULL nor a valid
               pointer.
 
-       EINTR  A signal occured while spu_run was in progress.  The  npc  value
+       EINTR  A signal occurred while spu_run was in progress.  The npc  value
               has  been updated to the new program counter value if necessary.
 
        EINVAL fd is not a file descriptor returned from spu_create(2).
index 89b1d196ca80fe3a0dfb4672fe0a36396e14ac32..4b5ca26e50485cef96afb94f1d6be4238bbe90af 100644 (file)
@@ -238,7 +238,7 @@ Top Level Directory Layout
 The sysfs directory arrangement exposes the relationship of kernel
 data structures. 
 
-The top level sysfs diretory looks like:
+The top level sysfs directory looks like:
 
 block/
 bus/
index 1773106976a26ebf7aaf425141797ea43f4563f1..6dd050878a2087269b9891f704177dc7f1dc1462 100644 (file)
@@ -39,7 +39,7 @@ tmpfs has the following uses:
        tmpfs   /dev/shm        tmpfs   defaults        0 0
 
    Remember to create the directory that you intend to mount tmpfs on
-   if necessary (/dev/shm is automagically created if you use devfs).
+   if necessary.
 
    This mount is _not_ needed for SYSV shared memory. The internal
    mount is used for that. (In the 2.3 kernel versions it was
@@ -63,7 +63,7 @@ size:      The limit of allocated bytes for this tmpfs instance. The
 nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE.
 nr_inodes: The maximum number of inodes for this instance. The default
            is half of the number of your physical RAM pages, or (on a
-           machine with highmem) the number of lowmem RAM pages,
+           machine with highmem) the number of lowmem RAM pages,
            whichever is the lower.
 
 These parameters accept a suffix k, m or g for kilo, mega and giga and
index 2001abbc60e6f599fc53abc3b746ce2effc75187..069cb10943001e92da62cd24c30000af5e50a930 100644 (file)
@@ -35,7 +35,7 @@ iocharset=name -- Character set to use for converting between the
                 you should consider the following option instead.
 
 utf8=<bool>   -- UTF-8 is the filesystem safe version of Unicode that
-                is used by the console.  It can be be enabled for the
+                is used by the console.  It can be enabled for the
                 filesystem with this option. If 'uni_xlate' gets set,
                 UTF-8 gets disabled.
 
index cd07c21b84005cb4e2cd3980f1c103ec94824662..7737bfd03cf8481e97717a849fc6c83887b7a94e 100644 (file)
@@ -410,7 +410,7 @@ otherwise noted.
 
   put_link: called by the VFS to release resources allocated by
        follow_link().  The cookie returned by follow_link() is passed
-       to to this method as the last parameter.  It is used by
+       to this method as the last parameter.  It is used by
        filesystems such as NFS where page cache is not stable
        (i.e. page that was installed when the symbolic link walk
        started might not be in the page cache at the end of the
index 11dcc56798873477dcbfd778b0a05cb6343ed2ed..db10250df6be66fc019e135604f761d9c947951c 100644 (file)
@@ -233,7 +233,7 @@ related kernel services:
      (*) __debug_mmu.iamr[]
      (*) __debug_mmu.damr[]
 
-        These receive the current IAMR and DAMR contents. These can be viewed with with the _amr
+        These receive the current IAMR and DAMR contents. These can be viewed with the _amr
         GDB macro:
 
                (gdb) _amr
index 2c33926b909923bc440fe7d01c2a67e38cde45a1..76034d9dbfc084ad01a8952ac1f80db26892bfc6 100644 (file)
@@ -57,7 +57,7 @@ What's left to be done for 32-bit UIDs on all Linux architectures:
 
   Other filesystems have not been checked yet.
 
-- The ncpfs and smpfs filesystems can not presently use 32-bit UIDs in
+- The ncpfs and smpfs filesystems cannot presently use 32-bit UIDs in
   all ioctl()s. Some new ioctl()s have been added with 32-bit UIDs, but
   more are needed. (as well as new user<->kernel data structures)
 
index 7620ff735faf9384a87f61ba6bf4ccdc7763b655..ce31f65e12e736130adba6116d1a0a51ff29fff1 100644 (file)
@@ -10,7 +10,7 @@ back and forth trying to integrate high-resolution and high-precision
 features into the existing timer framework, and after testing various
 such high-resolution timer implementations in practice, we came to the
 conclusion that the timer wheel code is fundamentally not suitable for
-such an approach. We initially didnt believe this ('there must be a way
+such an approach. We initially didn't believe this ('there must be a way
 to solve this'), and spent a considerable effort trying to integrate
 things into the timer wheel, but we failed. In hindsight, there are
 several reasons why such integration is hard/impossible:
@@ -27,7 +27,7 @@ several reasons why such integration is hard/impossible:
   high-res timers.
 
 - the unpredictable [O(N)] overhead of cascading leads to delays which
-  necessiate a more complex handling of high resolution timers, which
+  necessitate a more complex handling of high resolution timers, which
   in turn decreases robustness. Such a design still led to rather large
   timing inaccuracies. Cascading is a fundamental property of the timer
   wheel concept, it cannot be 'designed out' without unevitably
@@ -58,7 +58,7 @@ several reasons why such integration is hard/impossible:
 The primary users of precision timers are user-space applications that
 utilize nanosleep, posix-timers and itimer interfaces. Also, in-kernel
 users like drivers and subsystems which require precise timed events
-(e.g. multimedia) can benefit from the availability of a seperate
+(e.g. multimedia) can benefit from the availability of a separate
 high-resolution timer subsystem as well.
 
 While this subsystem does not offer high-resolution clock sources just
@@ -68,7 +68,7 @@ The increasing demand for realtime and multimedia applications along
 with other potential users for precise timers gives another reason to
 separate the "timeout" and "precise timer" subsystems.
 
-Another potential benefit is that such a seperation allows even more
+Another potential benefit is that such a separation allows even more
 special-purpose optimization of the existing timer wheel for the low
 resolution and low precision use cases - once the precision-sensitive
 APIs are separated from the timer wheel and are migrated over to
@@ -96,8 +96,8 @@ file systems. The rbtree is solely used for time sorted ordering, while
 a separate list is used to give the expiry code fast access to the
 queued timers, without having to walk the rbtree.
 
-(This seperate list is also useful for later when we'll introduce
-high-resolution clocks, where we need seperate pending and expired
+(This separate list is also useful for later when we'll introduce
+high-resolution clocks, where we need separate pending and expired
 queues while keeping the time-order intact.)
 
 Time-ordered enqueueing is not purely for the purposes of
index ede2c1e51cd7a9f1bde96640646ea34a1b269162..057e6bebda8fa9647f002594af962d131783af68 100644 (file)
@@ -26,7 +26,7 @@ to initialize the system view of the time during boot.
 Because we wanted to minimize the impact on existing user-level apps using
 the CMOS clock, we decided to expose an API that was very similar to the one
 used today with the legacy RTC driver (driver/char/rtc.c). However, because 
-EFI provides a simpler services, not all all ioctl() are available. Also
+EFI provides a simpler services, not all ioctl() are available. Also
 new ioctl()s have been introduced for things that EFI provides but not the 
 legacy.
 
index 28da181f9966f6e7ffaadc63ef67fafbe60ab400..59dd689d9b8649dd3f2b81859a97018531b3f4a3 100644 (file)
@@ -165,7 +165,7 @@ complicated cases.
 * Signal handling
 
 The delivery of (asynchronous) signals must be delayed until fsys-mode
-is exited.  This is acomplished with the help of the lower-privilege
+is exited.  This is accomplished with the help of the lower-privilege
 transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
 checks whether the interrupted task was in fsys-mode and, if so, sets
 PSR.lp and returns immediately.  When fsys-mode is exited via the
index a71cc6a67ef7b6c3e2762a9cf7822be87150201c..f097c60cba1b9ace6369919f90233a4465a97b52 100644 (file)
@@ -12,7 +12,7 @@ by locks is indeterminate, including linked lists.
 ---
 
 The complicated ia64 MCA process.  All of this is mandated by Intel's
-specification for ia64 SAL, error recovery and and unwind, it is not as
+specification for ia64 SAL, error recovery and unwind, it is not as
 if we have a choice here.
 
 * MCA occurs on one cpu, usually due to a double bit memory error.
@@ -94,7 +94,7 @@ if we have a choice here.
 
 INIT is less complicated than MCA.  Pressing the nmi button or using
 the equivalent command on the management console sends INIT to all
-cpus.  SAL picks one one of the cpus as the monarch and the rest are
+cpus.  SAL picks one of the cpus as the monarch and the rest are
 slaves.  All the OS INIT handlers are entered at approximately the same
 time.  The OS monarch prints the state of all tasks and returns, after
 which the slaves return and the system resumes.
index 8b3fd82b2ce712ead5c94b41f82972e58959200e..71aa403452722348f2a1668db3b6b35699e833df 100644 (file)
@@ -450,7 +450,7 @@ his laptop (the location of sensors may vary on other models):
 
 No commands can be written to this file.
 
-EXPERIMENTAL: Embedded controller reigster dump -- /proc/acpi/ibm/ecdump
+EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------
 
 This feature is marked EXPERIMENTAL because the implementation
index 29866fbfb229d22db36f08fa04e0513506fe4126..0bf38baa2db96a162e8f641eac90de097487cbf4 100644 (file)
@@ -281,7 +281,7 @@ Summary of ide driver parameters for kernel command line
 
  "idex=serialize"      : do not overlap operations on idex. Please note
                          that you will have to specify this option for
-                         both the respecitve primary and secondary channel
+                         both the respective primary and secondary channel
                          to take effect.
 
  "idex=four"           : four drives on idex and ide(x^1) share same ports
index 3b8b2d43a68e6cc8a6e2ba2b7098fcc574dd9a48..4f0e89df5c5191cbc166adc5f86e23f69aac6ba2 100644 (file)
@@ -79,10 +79,10 @@ JOY0DAT   Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0     X7  X6  X5  X4  X3  X2  X1  X0
 JOY1DAT   Y7  Y6  Y5  Y4  Y3  Y2  Y1  Y0     X7  X6  X5  X4  X3  X2  X1  X0
 
         0=LEFT CONTROLLER PAIR, 1=RIGHT CONTROLLER PAIR.
-        (4 counters total).The bit usage for both left and right
+        (4 counters total). The bit usage for both left and right
         addresses is shown below. Each 6 bit counter (Y7-Y2,X7-X2) is
         clocked by 2 of the signals input from the mouse serial
-        stream. Starting with first bit recived:
+        stream. Starting with first bit received:
 
          +-------------------+-----------------------------------------+
          | Serial | Bit Name | Description                             |
index 8fb896c74114af6670ce77cb40448c213715f6b4..1e7e5853ba4c71eafdbc1e9f57cc749826b658c4 100644 (file)
@@ -10,7 +10,7 @@ provides a convenient connection point for a mouse and switch-type joysticks.
 The ikbd processor also maintains a time-of-day clock with one second
 resolution.
 The ikbd has been designed to be general enough that it can be used with a
-ariety of new computer products. Product variations in a number of
+variety of new computer products. Product variations in a number of
 keyswitches, mouse resolution, etc. can be accommodated.
 The ikbd communicates with the main processor over a high speed bi-directional
 serial interface. It can function in a variety of modes to facilitate
@@ -30,7 +30,7 @@ is obtained by ORing 0x80 with the make code.
 The special codes 0xF6 through 0xFF are reserved for use as follows:
     0xF6            status report
     0xF7            absolute mouse position record
-    0xF8-0xFB       relative mouse position records(lsbs determind by
+    0xF8-0xFB       relative mouse position records (lsbs determined by
                      mouse button states)
     0xFC            time-of-day
     0xFD            joystick report (both sticks)
@@ -84,7 +84,7 @@ selected.
 4.2 Absolute Position reporting
 
 The ikbd can also maintain absolute mouse position. Commands exist for
-reseting the mouse position, setting X/Y scaling, and interrogating the
+resetting the mouse position, setting X/Y scaling, and interrogating the
 current mouse position.
 
 4.3 Mouse Cursor Key Mode
@@ -406,7 +406,7 @@ INTERROGATION MODE.
 9.18 SET JOYSTICK MONITORING
 
     0x17
-    rate                ; time between samples in hundreths of a second
+    rate                ; time between samples in hundredths of a second
     Returns: (in packets of two as long as in mode)
             %000000xy   ; where y is JOYSTICK1 Fire button
                         ; and x is JOYSTICK0 Fire button
@@ -522,7 +522,7 @@ controller memory. The time between data bytes must be less than 20ms.
             0x20        ; memory access
             { data }    ; 6 data bytes starting at ADR
 
-This comand permits the host to read from the ikbd controller memory.
+This command permits the host to read from the ikbd controller memory.
 
 9.26 CONTROLLER EXECUTE
 
index 6181747a14d8aea53af8fb618969ac8ab28181be..afe0d6543e093fa5dfa4758bbb0cbec90ff0bce3 100644 (file)
@@ -27,7 +27,7 @@ This driver have the basic support for PCI devices only; there is no
 ISA or PnP ISA cards supported. AFAIK the ns558 have support for Crystal 
 ISA and PnP ISA series.
 
-The driver works witn ALSA drivers simultaneously. For exmple, the xracer
+The driver works with ALSA drivers simultaneously. For example, the xracer
 uses joystick as input device and PCM device as sound output in one time.
 There are no sound or input collisions detected. The source code have
 comments about them; but I've found the joystick can be initialized 
index c53b1c11aa40959f082579c490a3ffe994811d08..085eb15b45b7c5655d0c8363e19bdde2cf4e4699 100644 (file)
@@ -38,7 +38,7 @@ joystick.txt for details.
 There is an utility called fftest that will allow you to test the driver.
 % fftest /dev/input/eventXX
 
-3. Instructions to the developper
+3. Instructions to the developer
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 All interactions are done using the event API. That is, you can use ioctl()
 and write() on /dev/input/eventXX.
index 1ba3d322e0acbe88cd7769d009e7cfa8438b9ff0..14e0a8b70225f5cce93c2cf8bdb85a0aa984b8ee 100644 (file)
@@ -18,8 +18,8 @@ Make sure struct gameport is initialized to 0 in all other fields. The
 gameport generic code will take care of the rest.
 
 If your hardware supports more than one io address, and your driver can
-choose which one program the hardware to, starting from the more exotic
-addresses is preferred, because the likelyhood of clashing with the standard
+choose which one to program the hardware to, starting from the more exotic
+addresses is preferred, because the likelihood of clashing with the standard
 0x201 address is smaller.
 
 Eg. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
index 47137e75fdb84d797ee4708ce542e4f55f4e7e3e..ff8cea0225f90bdce6c28adc5b3af5816f9eea44 100644 (file)
@@ -68,8 +68,8 @@ will be available as a character device on major 13, minor 63:
 
        crw-r--r--   1 root     root      13,  63 Mar 28 22:45 mice
 
-  This device has to be created, unless you use devfs, in which case it's
-created automatically. The commands to do create it by hand are:
+  This device has to be created.
+  The commands to create it by hand are:
 
        cd /dev
        mkdir input
@@ -154,7 +154,7 @@ about it.
 
 3.2 Event handlers
 ~~~~~~~~~~~~~~~~~~
-  Event handlers distrubite the events from the devices to userland and
+  Event handlers distribute the events from the devices to userland and
 kernel, as needed.
 
 3.2.1 keybdev
@@ -230,7 +230,7 @@ generated in the kernel straight to the program, with timestamps. The
 API is still evolving, but should be useable now. It's described in
 section 5. 
 
-  This should be the way for GPM and X to get keyboard and mouse mouse
+  This should be the way for GPM and X to get keyboard and mouse
 events. It allows for multihead in X without any specific multihead
 kernel support. The event codes are the same on all architectures and
 are hardware independent.
@@ -279,7 +279,7 @@ struct input_event {
 };
 
   'time' is the timestamp, it returns the time at which the event happened.
-Type is for example EV_REL for relative momement, REL_KEY for a keypress or
+Type is for example EV_REL for relative moment, REL_KEY for a keypress or
 release. More types are defined in include/linux/input.h.
 
   'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
@@ -289,24 +289,3 @@ list is in include/linux/input.h.
 EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
 release, 1 for keypress and 2 for autorepeat.
 
-6. Contacts
-~~~~~~~~~~~
-  This effort has its home page at:
-
-       http://www.suse.cz/development/input/
-
-You'll find both the latest HID driver and the complete Input driver
-there as well as information how to access the CVS repository for
-latest revisions of the drivers.
-
-  There is also a mailing list for this:
-
-       majordomo@atrey.karlin.mff.cuni.cz
-
-Send "subscribe linux-input" to subscribe to it.
-
-The input changes are also being worked on as part of the LinuxConsole
-project, see:
-
-        http://sourceforge.net/projects/linuxconsole/
-
index d537c48cc6d02d0541b44271698f6997e90332e4..ede5f33daad3dbc0f7346654a348fd4eb28d7387 100644 (file)
@@ -456,8 +456,8 @@ uses the following kernel/module command line:
          8  | Sony PSX DDR controller
          9  | SNES mouse
 
-  The exact type of the PSX controller type is autoprobed when used so
-hot swapping should work (but is not recomended).
+  The exact type of the PSX controller type is autoprobed when used, so
+hot swapping should work (but is not recommended).
 
   Should you want to use more than one of parallel ports at once, you can use
 gamecon.map2 and gamecon.map3 as additional command line parameters for two
@@ -465,8 +465,8 @@ more parallel ports.
 
   There are two options specific to PSX driver portion.  gamecon.psx_delay sets
 the command delay when talking to the controllers. The default of 25 should
-work but you can try lowering it for better performace. If your pads don't
-respond try raising it untill they work. Setting the type to 8 allows the
+work but you can try lowering it for better performance. If your pads don't
+respond try raising it until they work. Setting the type to 8 allows the
 driver to be used with Dance Dance Revolution or similar games. Arrow keys are
 registered as key presses instead of X and Y axes.
 
index 841c353297e6e0819fc37a6d520500809d20140d..389de9bd987894017bb25ddc95b911c98526bdcb 100644 (file)
@@ -60,7 +60,7 @@ and install it before going on.
 
 2.2 Device nodes
 ~~~~~~~~~~~~~~~~
-For applications to be able to use the joysticks, in you don't use devfs,
+For applications to be able to use the joysticks,
 you'll have to manually create these nodes in /dev:
 
 cd /dev
index 0962c5c948beed9282550009e6c04f1bcdf6ebd1..0a8c97e87d47ee6fce48dbe96ff93e6c42d6fa5d 100644 (file)
@@ -87,13 +87,13 @@ Line 3  Format                      : 888888888888
 
 
 Format description:
-  From a user space perspective the world is seperated in "digits" and "icons".
+  From a userspace perspective the world is separated into "digits" and "icons".
   A digit can have a character set, an icon can only be ON or OFF.
 
   Format specifier
     '8' :  Generic 7 segment digit with individual addressable segments
 
-    Reduced capabillity 7 segm digit, when segments are hard wired together.
+    Reduced capability 7 segm digit, when segments are hard wired together.
     '1' : 2 segments digit only able to produce a 1.
     'e' : Most significant day of the month digit,
           able to produce at least 1 2 3.
index 11c9be49f37caa1a80e9f558c78f21a8e8aebae1..c19efdeace2cd220a73554b66f5c0fbef1d81d0b 100644 (file)
@@ -203,7 +203,7 @@ HDIO_SET_MULTCOUNT          change IDE blockmode
 
          Source code comments read:
 
-           This is tightly woven into the driver->do_special can not
+           This is tightly woven into the driver->do_special cannot
            touch.  DON'T do it again until a total personality rewrite
            is committed.
 
index 7e5731319e30d6b0b5361bff7c94c2952f5d2a97..9c8c6d914ec79788a367082663d60c9a51865148 100644 (file)
@@ -26,7 +26,7 @@ Structure T30_s description:
   If the HL-driver receives ISDN_CMD_FAXCMD, all needed information
   is in this struct set by the LL.
   To signal information to the LL, the HL-driver has to set the 
-  the parameters and use ISDN_STAT_FAXIND.
+  parameters and use ISDN_STAT_FAXIND.
   (Please refer to INTERFACE)
 
 Structure T30_s:
index 56cc59df1fb75acda538632a5005db7eaa811088..eeca11f00ccd0287a67036a4ccf7a90f4ae15f62 100644 (file)
@@ -1,6 +1,6 @@
 $Id: README.hysdn,v 1.3.6.1 2001/02/10 14:41:19 kai Exp $
 The hysdn driver has been written by
-by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) 
+Werner Cornelius (werner@isdn4linux.de or werner@titro.de)
 for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
 under the GNU General Public License.
 
index e4814c21330108377536cfa3c4e706854acb580b..c768dc63b34e9c73c629a7e15b6444d76a8692e9 100644 (file)
@@ -22,7 +22,7 @@ other program after you have done the following:
    the kernel (CONFIG_BINFMT_MISC) and set it up properly.
    If you choose to compile it as a module, you will have
    to insert it manually with modprobe/insmod, as kmod
-   can not easily be supported with binfmt_misc. 
+   cannot easily be supported with binfmt_misc. 
    Read the file 'binfmt_misc.txt' in this directory to know
    more about the configuration process.
 
index 003fccc14d241bfb5445aec93e13d9ead4ac5d25..125093c3ef76229296c171167c726c32d8e82b1a 100644 (file)
@@ -1,7 +1,7 @@
 Introduction
 ------------
 
-The configuration database is collection of configuration options
+The configuration database is collection of configuration options
 organized in a tree structure:
 
        +- Code maturity level options
@@ -110,7 +110,7 @@ applicable everywhere (see syntax).
   the indentation level, this means it ends at the first line which has
   a smaller indentation than the first line of the help text.
   "---help---" and "help" do not differ in behaviour, "---help---" is
-  used to help visually seperate configuration logic from help within
+  used to help visually separate configuration logic from help within
   the file as an aid to developers.
 
 
@@ -226,7 +226,7 @@ menuconfig:
        "menuconfig" <symbol>
        <config options>
 
-This is similiar to the simple config entry above, but it also gives a
+This is similar to the simple config entry above, but it also gives a
 hint to front ends, that all suboptions should be displayed as a
 separate list of options.
 
index e2cbd59cf2d0bdcf82ba99064dbf50b86b976f38..50f4eddf899cac4a06724355a2fd26299ab6909d 100644 (file)
@@ -390,7 +390,7 @@ more details, with real examples.
        The kernel may be built with several different versions of
        $(CC), each supporting a unique set of features and options.
        kbuild provide basic support to check for valid options for $(CC).
-       $(CC) is useally the gcc compiler, but other alternatives are
+       $(CC) is usually the gcc compiler, but other alternatives are
        available.
 
     as-option
index 08bafa8c1caa91058a2d1c1eb91128e70668781d..99f2d4d4bf7ddb18218a4bc3a089aaf51fa5f993 100644 (file)
@@ -249,7 +249,7 @@ If die() is called, and it happens to be a thread with pid 0 or 1, or die()
 is called inside interrupt context or die() is called and panic_on_oops is set,
 the system will boot into the dump-capture kernel.
 
-On powererpc systems when a soft-reset is generated, die() is called by all cpus and the system system will boot into the dump-capture kernel.
+On powererpc systems when a soft-reset is generated, die() is called by all cpus and the system will boot into the dump-capture kernel.
 
 For testing purposes, you can trigger a crash by using "ALT-SysRq-c",
 "echo c > /proc/sysrq-trigger or write a module to force the panic.
index 99d24f2943eefc1ae597c09470e00964fc8fa356..b53bccbd97270f37871964fda6ba46b0f706365a 100644 (file)
        Description: Very nice 92 pages GPL book on the topic of modules
        programming. Lots of examples.
        
-     * Title: "Device File System (devfs) Overview"
-       Author: Richard Gooch.
-       URL: http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html
-       Keywords: filesystem, /dev, devfs, dynamic devices, major/minor
-       allocation, device management.
-       Description: Document describing Richard Gooch's controversial
-       devfs, which allows for dynamic devices, only shows present
-       devices in /dev, gets rid of major/minor numbers allocation
-       problems, and allows for hundreds of identical devices (which some
-       USB systems might demand soon).
-       
      * Title: "I/O Event Handling Under Linux"
        Author: Richard Gooch.
        URL: http://www.atnf.csiro.au/~rgooch/linux/docs/io-events.html
index 137e993f4329aa9c6cc83a7835dcc9380312dbd6..ff571f9298e0530bb38d3ffdaabea01f1b4aec17 100644 (file)
@@ -289,9 +289,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        autotest        [IA64]
 
-       awe=            [HW,OSS] AWE32/SB32/AWE64 wave table synth
-                       Format: <io>,<memsize>,<isapnp>
-
        aztcd=          [HW,CD] Aztech CD268 CDROM driver
                        Format: <io>,0x79 (?)
 
@@ -355,9 +352,9 @@ and is between 256 and 4096 characters. It is defined in the file
 
        clock=          [BUGS=IA-32, HW] gettimeofday clocksource override.
                        [Deprecated]
-                       Forces specified clocksource (if avaliable) to be used
+                       Forces specified clocksource (if available) to be used
                        when calculating gettimeofday(). If specified
-                       clocksource is not avalible, it defaults to PIT.
+                       clocksource is not available, it defaults to PIT.
                        Format: { pit | tsc | cyclone | pmtmr }
 
        disable_8254_timer
@@ -536,10 +533,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Default value is 0.
                        Value can be changed at runtime via /selinux/enforce.
 
-       es1370=         [HW,OSS]
-                       Format: <lineout>[,<micbias>]
-                       See also header of sound/oss/es1370.c.
-
        es1371=         [HW,OSS]
                        Format: <spdif>,[<nomix>,[<amplifier>]]
                        See also header of sound/oss/es1371.c.
@@ -580,9 +573,6 @@ and is between 256 and 4096 characters. It is defined in the file
        gscd=           [HW,CD]
                        Format: <io>
 
-       gus=            [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma16>
-
        gvp11=          [HW,SCSI]
 
        hashdist=       [KNL,NUMA] Large hashes allocated during boot
@@ -611,8 +601,8 @@ and is between 256 and 4096 characters. It is defined in the file
        noirqbalance    [IA-32,SMP,KNL] Disable kernel irq balancing
 
        i8042.direct    [HW] Put keyboard port into non-translated mode
-       i8042.dumbkbd   [HW] Pretend that controlled can only read data from
-                            keyboard and can not control its state
+       i8042.dumbkbd   [HW] Pretend that controller can only read data from
+                            keyboard and cannot control its state
                             (Don't attempt to blink the leds)
        i8042.noaux     [HW] Don't check for auxiliary (== mouse) port
        i8042.nokbd     [HW] Don't check/create keyboard port
@@ -841,12 +831,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        (machvec) in a generic kernel.
                        Example: machvec=hpzx1_swiotlb
 
-       mad16=          [HW,OSS] Format:
-                       <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
-
-       maui=           [HW,OSS]
-                       Format: <io>,<irq>
-
        max_loop=       [LOOP] Maximum number of loopback devices that can
                        be mounted
                        Format: <1-256>
@@ -1114,9 +1098,6 @@ and is between 256 and 4096 characters. It is defined in the file
        opl3=           [HW,OSS]
                        Format: <io>
 
-       opl3sa=         [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma2>,<mpu_io>,<mpu_irq>
-
        opl3sa2=        [HW,OSS] Format:
                        <io>,<irq>,<dma>,<dma2>,<mss_io>,<mpu_io>,<ymode>,<loopback>[,<isapnp>,<multiple]
 
@@ -1357,10 +1338,6 @@ and is between 256 and 4096 characters. It is defined in the file
        rcu.qlowmark=   [KNL,BOOT] Set threshold of queued
                        RCU callbacks below which batch limiting is re-enabled.
 
-       rcu.rsinterval= [KNL,BOOT,SMP] Set the number of additional
-                       RCU callbacks to queued before forcing reschedule
-                       on all cpus.
-
        rdinit=         [KNL]
                        Format: <full_path>
                        Run specified binary instead of /init from the ramdisk,
@@ -1368,7 +1345,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        reboot=         [BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
                        Format: <reboot_mode>[,<reboot_mode2>[,...]]
-                       See arch/*/kernel/reboot.c.
+                       See arch/*/kernel/reboot.c or arch/*/kernel/process.c                   
 
        reserve=        [KNL,BUGS] Force the kernel to ignore some iomem area
 
@@ -1455,9 +1432,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        sg_def_reserved_size=   [SCSI]
 
-       sgalaxy=        [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma2>,<sgbase>
-
        shapers=        [NET]
                        Maximal number of shapers.
 
@@ -1598,9 +1572,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        snd-ymfpci=     [HW,ALSA]
 
-       sonicvibes=     [HW,OSS]
-                       Format: <reverb>
-
        sonycd535=      [HW,CD]
                        Format: <io>[,<irq>]
 
index e373f02128434277bc53098185b393df0a7c36d5..3da586bc7859a3f982255547472fcfd5193eaf6a 100644 (file)
@@ -671,7 +671,7 @@ The keyctl syscall functions are:
 
      Note that this setting is inherited across fork/exec.
 
-     [1] The default default is: the thread keyring if there is one, otherwise
+     [1] The default is: the thread keyring if there is one, otherwise
      the process keyring if there is one, otherwise the session keyring if
      there is one, otherwise the user default session keyring.
 
@@ -708,14 +708,14 @@ The keyctl syscall functions are:
 
      If the specified key is 0, then any assumed authority will be divested.
 
-     The assumed authorititive key is inherited across fork and exec.
+     The assumed authoritative key is inherited across fork and exec.
 
 
 ===============
 KERNEL SERVICES
 ===============
 
-The kernel services for key managment are fairly simple to deal with. They can
+The kernel services for key management are fairly simple to deal with. They can
 be broken down into two areas: keys and key types.
 
 Dealing with keys is fairly straightforward. Firstly, the kernel service
index 949f7b5a20538aa3537078d0eafd636df4a5991b..e44855513b3d4f044177d871a8af7b8383c3fa59 100644 (file)
@@ -51,7 +51,7 @@ more complex object types. It provides a set of basic fields that
 almost all complex data types share. kobjects are intended to be
 embedded in larger data structures and replace fields they duplicate. 
 
-1.2 Defintion
+1.2 Definition
 
 struct kobject {
        char                    name[KOBJ_NAME_LEN];
index 5696e879449bca5c7353804d5fca069cd9926f46..c487186eb2b93ac9a0180561396470bce867e4b3 100644 (file)
@@ -152,7 +152,7 @@ loaded on demand while the application executes) and sequentially accessed data
 DO_REMOUNTS:
 
 The control script automatically remounts any mounted journaled filesystems
-with approriate commit interval options. When this option is set to 0, this
+with appropriate commit interval options. When this option is set to 0, this
 feature is disabled.
 
 DO_REMOUNT_NOATIME:
index 55a7e4fa8cc2b5d37635188475d15e6e9268073e..dab123db5a4fed62b324b9ffe2624fc04c0b5846 100644 (file)
@@ -133,7 +133,7 @@ cases there is an inherent "natural" ordering between the two objects
 (defined by the properties of the hierarchy), and the kernel grabs the
 locks in this fixed order on each of the objects.
 
-An example of such an object hieararchy that results in "nested locking"
+An example of such an object hierarchy that results in "nested locking"
 is that of a "whole disk" block-dev object and a "partition" block-dev
 object; the partition is "part of" the whole device and as long as one
 always takes the whole disk lock as a higher lock than the partition
@@ -158,11 +158,11 @@ enum bdev_bd_mutex_lock_class
 In this case the locking is done on a bdev object that is known to be a
 partition.
 
-The validator treats a lock that is taken in such a nested fasion as a
+The validator treats a lock that is taken in such a nested fashion as a
 separate (sub)class for the purposes of validation.
 
 Note: When changing code to use the _nested() primitives, be careful and
-check really thoroughly that the hiearchy is correctly mapped; otherwise
+check really thoroughly that the hierarchy is correctly mapped; otherwise
 you can get false positives or false negatives.
 
 Proof of 100% correctness:
@@ -170,7 +170,7 @@ Proof of 100% correctness:
 
 The validator achieves perfect, mathematical 'closure' (proof of locking
 correctness) in the sense that for every simple, standalone single-task
-locking sequence that occured at least once during the lifetime of the
+locking sequence that occurred at least once during the lifetime of the
 kernel, the validator proves it with a 100% certainty that no
 combination and timing of these locking sequences can cause any class of
 lock related deadlock. [*]
index d5d3f064f5522a42563bf9b6dded805dfb3f091b..1c41db21d3c16576c1edb8b78d4b5fd6ae5cba82 100644 (file)
@@ -415,7 +415,7 @@ switch to another mode once Linux has started.
 
   The first 3 parameters of this sub-option should be obvious: <xres>,
 <yres> and <depth> give the dimensions of the screen and the number of
-planes (depth). The depth is is the logarithm to base 2 of the number
+planes (depth). The depth is the logarithm to base 2 of the number
 of colors possible. (Or, the other way round: The number of colors is
 2^depth).
 
index 60913354cb7dcf898ef96f9381bb555cd9f92af4..aabce4ad90f98fefce10850c04bbae8ab81b7ef3 100644 (file)
@@ -177,7 +177,7 @@ Currently, there are a number of MCA-specific device drivers.
        with clones that have a different adapter id than the original
        NE/2.
 
-6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Aapter/A and
+6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Adapter/A and
    Reply Sound Blaster/SCSI (SCSI part)
        Better support for these cards than the driver for ISA.
    Supports multiple cards with IRQ sharing.
index 9ae9e40789858c36895c976c8cc606de5332c14e..2202f5dc8ac208381a241bd5fc6b56b73c81ea9a 100644 (file)
@@ -62,7 +62,7 @@ be reconstructed (due to no parity).
 
 For this reason, md will normally refuse to start such an array.  This
 requires the sysadmin to take action to explicitly start the array
-desipite possible corruption.  This is normally done with
+despite possible corruption.  This is normally done with
    mdadm --assemble --force ....
 
 This option is not really available if the array has the root
@@ -175,7 +175,7 @@ All md devices contain:
      raid levels that involve striping (1,4,5,6,10). The address space
      of the array is conceptually divided into chunks and consecutive
      chunks are striped onto neighbouring devices.
-     The size should be atleast PAGE_SIZE (4k) and should be a power
+     The size should be at least PAGE_SIZE (4k) and should be a power
      of 2.  This can only be set while assembling an array
 
   component_size
@@ -214,8 +214,8 @@ All md devices contain:
    safe_mode_delay
      When an md array has seen no write requests for a certain period
      of time, it will be marked as 'clean'.  When another write
-     request arrive, the array is marked as 'dirty' before the write
-     commenses.  This is known as 'safe_mode'.
+     request arrives, the array is marked as 'dirty' before the write
+     commences.  This is known as 'safe_mode'.
      The 'certain period' is controlled by this file which stores the
      period as a number of seconds.  The default is 200msec (0.200).
      Writing a value of 0 disables safemode.
@@ -307,8 +307,8 @@ Each directory contains:
                         This applies only to raid1 arrays.
              spare    - device is working, but not a full member.
                         This includes spares that are in the process
-                        of being recoverred to
-       This list make grow in future.
+                        of being recovered to
+       This list may grow in future.
        This can be written to.
        Writing "faulty"  simulates a failure on the device.
        Writing "remove" removes the device from the array.
@@ -330,7 +330,7 @@ Each directory contains:
         This gives the role that the device has in the array.  It will
        either be 'none' if the device is not active in the array
         (i.e. is a spare or has failed) or an integer less than the
-       'raid_disks' number for the array indicating which possition
+       'raid_disks' number for the array indicating which position
        it currently fills.  This can only be set while assembling an
        array.  A device for which this is set is assumed to be working.
 
@@ -353,7 +353,7 @@ in the array.  These are named
 
     rdNN
 
-where 'NN' is the possition in the array, starting from 0.
+where 'NN' is the position in the array, starting from 0.
 So for a 3 drive array there will be rd0, rd1, rd2.
 These are symbolic links to the appropriate 'dev-XXX' entry.
 Thus, for example,
index 46b9b389df35c52cf90ac544ea538f2e23c54361..994355b0cd19087654d8cab690597944ed633a0a 100644 (file)
@@ -670,7 +670,7 @@ effectively random order, despite the write barrier issued by CPU 1:
 
 
 In the above example, CPU 2 perceives that B is 7, despite the load of *C
-(which would be B) coming after the the LOAD of C.
+(which would be B) coming after the LOAD of C.
 
 If, however, a data dependency barrier were to be placed between the load of C
 and the load of *C (ie: B) on CPU 2:
@@ -1915,7 +1915,7 @@ Whilst most CPUs do imply a data dependency barrier on the read when a memory
 access depends on a read, not all do, so it may not be relied on.
 
 Other CPUs may also have split caches, but must coordinate between the various
-cachelets for normal memory accesss.  The semantics of the Alpha removes the
+cachelets for normal memory accesses.  The semantics of the Alpha removes the
 need for coordination in absence of memory barriers.
 
 
index 807a0c7b4737c60fe8d119d54b65ebf4ba80af10..e8e1758e87dab7244d1b92a2c4400764e53bb687 100644 (file)
@@ -26,7 +26,7 @@ other program after you have done the following:
    the kernel (CONFIG_BINFMT_MISC) and set it up properly.
    If you choose to compile it as a module, you will have
    to insert it manually with modprobe/insmod, as kmod
-   can not be easily supported with binfmt_misc. 
+   cannot be easily supported with binfmt_misc. 
    Read the file 'binfmt_misc.txt' in this directory to know
    more about the configuration process.
 
index 867a99f88c68459cd92c95a81a85f395e4e97cd6..0643e3b7168cccb44acf65735c71beb5e273845c 100644 (file)
@@ -126,7 +126,7 @@ packets faster than they can be removed from the card. This should be rare
 or impossible in normal operation. Possible causes of this error report are:
  
    - a "green" mode enabled that slows the processor down when there is no
-     keyboard activitiy. 
+     keyboard activity. 
 
    - some other device or device driver hogging the bus or disabling interrupts.
      Check /proc/interrupts for excessive interrupt counts. The timer tick
index 54376e8249c148181a458499bfa7517af4f8aa3e..93af3e87c65b470828d1fd62193c2ac5590a3e75 100644 (file)
@@ -35,7 +35,7 @@ Legend:
 packets out of the rx ring. Note from this that the lower the
 load the more we could clean up the rxring
 "Ndone" == is the converse of "Done". Note again, that the higher
-the load the more times we couldnt clean up the rxring.
+the load the more times we couldn't clean up the rxring.
 
 Observe that:
 when the NIC receives 890Kpackets/sec only 17 rx interrupts are generated. 
index 30a5f01403d391497043f24f118d389dbde1c05c..731de411513cf1a5685035b7b0df8f68c160beab 100644 (file)
@@ -139,7 +139,7 @@ And now to the cabling.  What you can connect together:
 
 5. An active hub to passive hub.
 
-Remember, that you can not connect two passive hubs together.  The power loss
+Remember that you cannot connect two passive hubs together.  The power loss
 implied by such a connection is too high for the net to operate reliably.
 
 An example of a typical ARCnet network:
index dc942eaf490fb8474a136f10a132d375d7759635..de809e58092fa070caa7fac46c6cc9bbac12aed4 100644 (file)
@@ -1023,7 +1023,7 @@ Changing a Bond's Configuration
 files located in /sys/class/net/<bond name>/bonding
 
        The names of these files correspond directly with the command-
-line parameters described elsewhere in in this file, and, with the
+line parameters described elsewhere in this file, and, with the
 exception of arp_ip_target, they accept the same values.  To see the
 current setting, simply cat the appropriate file.
 
index 188beb7d6a17271303c16725ef78d84623897193..64896470e279b7d4675c46c4673e024026bd815c 100644 (file)
@@ -227,7 +227,7 @@ configuration options are available on the command line:
 * media=rj45           - specify media type
    or media=bnc
    or media=aui
-   or medai=auto
+   or media=auto
 * duplex=full          - specify forced half/full/autonegotiate duplex
    or duplex=half
    or duplex=auto
@@ -584,7 +584,7 @@ of four ways after installing and or configuring the CS8900/20-based adapter:
 
     1.) The system does not boot properly (or at all).
 
-    2.) The driver can not communicate with the adapter, reporting an "Adapter
+    2.) The driver cannot communicate with the adapter, reporting an "Adapter
         not found" error message.
 
     3.) You cannot connect to the network or the driver will not load.
@@ -684,7 +684,7 @@ ethernet@crystal.cirrus.com) and request that you be registered for automatic
 software-update notification.
 
 Cirrus Logic maintains a web page at http://www.cirrus.com with the
-the latest drivers and technical publications.
+latest drivers and technical publications.
 
 
 6.4 Current maintainer
index 76324638626bc3a29bdff035c956c888baae0b00..20a887615c4ae8c08b708ff1f8c099e5c411b426 100644 (file)
@@ -56,7 +56,7 @@ FEATURES
 
       ethtool -C eth0 rx-usecs 100
 
-  You may also provide a timer latency value while disabling adpative-rx:
+  You may also provide a timer latency value while disabling adaptive-rx:
 
       ethtool -C <interface> adaptive-rx off rx-usecs <microseconds>
 
@@ -172,7 +172,7 @@ PERFORMANCE
    smaller window prevents congestion and facilitates better pacing,
    especially if/when MAC level flow control does not work well or when it is
    not supported on the machine. Experimentation may be necessary to attain
-   the correct value. This method is provided as a starting point fot the
+   the correct value. This method is provided as a starting point for the
    correct receive buffer size.
    Setting the min, max, and default receive buffer (RX_WINDOW) size is
    performed in the same manner as single connection.
index e6c39c5831f5f4059ebfbeefb597991221185543..badb7480ea6282904d7ff648629262fa0f632a97 100644 (file)
@@ -82,7 +82,7 @@ ethernet address of your ethernet card has to be set according to the DECnet
 address of the node in order for it to be autoconfigured (and then appear in
 /proc/net/decnet_dev). There is a utility available at the above
 FTP sites called dn2ethaddr which can compute the correct ethernet
-address to use. The address can be set by ifconfig either before at
+address to use. The address can be set by ifconfig either before or
 at the time the device is brought up. If you are using RedHat you can
 add the line:
 
index d460492037ef24bb231ab31732d25021410e4478..10e8490fa406b1bc3f237d89c822df0bbb68dbd9 100644 (file)
@@ -173,7 +173,7 @@ Installing the Driver
 
 Parameter Description
 =====================
-You can install this driver without any addtional parameter. However, if you
+You can install this driver without any additional parameter. However, if you
 are going to have extensive functions then it is necessary to set extra
 parameter. Below is a list of the command line parameters supported by the
 Linux device
@@ -222,7 +222,7 @@ rx_timeout=n                        - Rx DMA wait time for an interrupt.
                                  reach timeout of n * 640 nano seconds. 
                                  Set proper rx_coalesce and rx_timeout can 
                                  reduce congestion collapse and overload which
-                                 has been a bottlenect for high speed network.
+                                 has been a bottleneck for high speed network.
                                  
                                  For example, rx_coalesce=10 rx_timeout=800.
                                  that is, hardware assert only 1 interrupt 
index 046363552d09605937c1a23fc481db0cdbc9af21..b1b7499dd9d33703f431f96710d523a16d0757a1 100644 (file)
@@ -34,7 +34,7 @@ Next you should configure your network interface with a command similar to :
 
        ifconfig eth0 172.22.3.18
                       ^^^^^^^^^^^
-                    Your IP Adress
+                    Your IP Address
 
 Then you may have to modify the default routing table with command :
 
index a9ad58b49cc5459c82789bce189d9af51f77344e..4f7da5a2bf4f8ce7c3300f49fae7e073cdf51380 100644 (file)
@@ -37,7 +37,7 @@ Transmit path guidelines:
                ...
        }
 
-   And then at the end of your TX reclaimation event handling:
+   And then at the end of your TX reclamation event handling:
 
        if (netif_queue_stopped(dp->dev) &&
             TX_BUFFS_AVAIL(dp) > (MAX_SKB_FRAGS + 1))
index 71fe15af356cda609a2a0abae7b11bff1be1df0a..5c0a5cc039981926afe71b2a9009c70405e1a95b 100644 (file)
@@ -350,7 +350,7 @@ Additional Configurations
 
   As an example, if you install the e1000 driver for two PRO/1000 adapters
   (eth0 and eth1) and set the speed and duplex to 10full and 100half, add
-  the following to modules.conf or or modprobe.conf:
+  the following to modules.conf or modprobe.conf:
 
        alias eth0 e1000
        alias eth1 e1000
index f50d0c673c57e52682d9471b220e0b282f875737..0723db7f8495a1a0466ae06cd311c3e72ce24337 100644 (file)
@@ -79,7 +79,7 @@ trie_rebalance()
 
 resize()
        Analyzes a tnode and optimizes the child array size by either inflating
-       or shrinking it repeatedly until it fullfills the criteria for optimal
+       or shrinking it repeatedly until it fulfills the criteria for optimal
        level compression. This part follows the original paper pretty closely
        and there may be some room for experimentation here.
 
index c3297f79c137ecf14e8dc3bf9f05d26e3f804d8f..70e6275b757a46c786cd1e48f3532317a6c15b65 100644 (file)
@@ -79,8 +79,8 @@ Rate Estimator:
 
 0) Prepare an estimator attribute. Most likely this would be in user
    space. The value of this TLV should contain a tc_estimator structure.
-   As usual, such a TLV nees to be 32 bit aligned and therefore the
-   length needs to be appropriately set etc. The estimator interval
+   As usual, such a TLV needs to be 32 bit aligned and therefore the
+   length needs to be appropriately set, etc. The estimator interval
    and ewma log need to be converted to the appropriate values.
    tc_estimator.c::tc_setup_estimator() is advisable to be used as the
    conversion routine. It does a few clever things. It takes a time
@@ -103,8 +103,8 @@ In the kernel when setting up:
    else
        failed
 
-From now on, everytime you dump my_rate_est_stats it will contain
-uptodate info.
+From now on, every time you dump my_rate_est_stats it will contain
+up-to-date info.
 
 Once you are done, call gen_kill_estimator(my_basicstats,
 my_rate_est_stats) Make sure that my_basicstats and my_rate_est_stats
index 935e298f674adf846d4b4038939e5e17128c7b95..fd3c0c012351b7f15716d9314ffcb404c54f1693 100644 (file)
@@ -495,7 +495,7 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN
 
        Note that if no primary address exists for the interface selected,
        then the primary address of the first non-loopback interface that
-       has one will be used regarldess of this setting.
+       has one will be used regardless of this setting.
 
        Default: 0
 
@@ -787,7 +787,7 @@ accept_ra_defrtr - BOOLEAN
                            disabled if accept_ra is disabled.
 
 accept_ra_pinfo - BOOLEAN
-       Learn Prefix Inforamtion in Router Advertisement.
+       Learn Prefix Information in Router Advertisement.
 
        Functional default: enabled if accept_ra is enabled.
                            disabled if accept_ra is disabled.
index 53618fb1a717d6e5a1807118520857c2c7dc6748..1caa6c734691bc8bc2d14493065ae6f08613f5e6 100644 (file)
@@ -52,6 +52,6 @@ messages is high, but should have no other impact.
 Netconsole was designed to be as instantaneous as possible, to
 enable the logging of even the most critical kernel bugs. It works
 from IRQ contexts as well, and does not enable interrupts while
-sending packets. Due to these unique needs, configuration can not
+sending packets. Due to these unique needs, configuration cannot
 be more automatic, and some fundamental limitations will remain:
 only IP networks, UDP packets and ethernet devices are supported.
index 18ad4cea62592cd5ec2cc88578b2e92127a463f5..c967ddb90d0b1c37bc901922585ce1f561b5ad76 100644 (file)
@@ -40,7 +40,7 @@ History
    Per-interface rather than per-driver message level setting.
    More selective control over the type of messages emitted.
 
- The netif_msg recommandation adds these features with only a minor
+ The netif_msg recommendation adds these features with only a minor
  complexity and code size increase.
 
  The recommendation is the following points
index 4a21d9bb836b7345350b25f68e7bf0e1e76a508c..c9074f9b78bb7f2b25df1607c37953fdc7b6aa47 100644 (file)
@@ -2,7 +2,7 @@
 1. Introduction
 
 Linux distinguishes between administrative and operational state of an
-interface. Admininstrative state is the result of "ip link set dev
+interface. Administrative state is the result of "ip link set dev
 <dev> up or down" and reflects whether the administrator wants to use
 the device for traffic.
 
index aaf99d5f0dad6455f83c4ef811e907d83c98cec1..12a008a5c22158999b94dbb0693de65469b3a59c 100644 (file)
@@ -66,7 +66,7 @@ the following process:
 
 [setup]     socket() -------> creation of the capture socket
             setsockopt() ---> allocation of the circular buffer (ring)
-            mmap() ---------> maping of the allocated buffer to the
+            mmap() ---------> mapping of the allocated buffer to the
                               user process
 
 [capture]   poll() ---------> to wait for incoming packets
@@ -93,7 +93,7 @@ The destruction of the socket and all associated resources
 is done by a simple call to close(fd).
 
 Next I will describe PACKET_MMAP settings and it's constraints,
-also the maping of the circular buffer in the user process and 
+also the mapping of the circular buffer in the user process and 
 the use of this buffer.
 
 --------------------------------------------------------------------------------
@@ -153,8 +153,8 @@ we will get the following buffer structure:
 
 A frame can be of any size with the only condition it can fit in a block. A block
 can only hold an integer number of frames, or in other words, a frame cannot 
-be spawn accross two blocks so there are some datails you have to take into 
-account when choosing the frame_size. See "Maping and use of the circular 
+be spawned accross two blocks, so there are some details you have to take into 
+account when choosing the frame_size. See "Mapping and use of the circular 
 buffer (ring)".
 
 
@@ -215,8 +215,8 @@ called pg_vec, its size limits the number of blocks that can be allocated.
      block #1
 
 
-kmalloc allocates any number of bytes of phisically contiguous memory from 
-a pool of pre-determined sizes. This pool of memory is mantained by the slab 
+kmalloc allocates any number of bytes of physically contiguous memory from 
+a pool of pre-determined sizes. This pool of memory is maintained by the slab 
 allocator which is at the end the responsible for doing the allocation and 
 hence which imposes the maximum memory that kmalloc can allocate. 
 
@@ -262,7 +262,7 @@ i386 architecture:
        <pagesize> = 4096 bytes
        <max-order> = 11
 
-and a value for <frame size> of 2048 byteas. These parameters will yield
+and a value for <frame size> of 2048 bytes. These parameters will yield
 
        <block number> = 131072/4 = 32768 blocks
        <block size> = 4096 << 11 = 8 MiB.
@@ -278,7 +278,7 @@ an i386 kernel's memory size is limited to 1GiB.
 All memory allocations are not freed until the socket is closed. The memory 
 allocations are done with GFP_KERNEL priority, this basically means that 
 the allocation can wait and swap other process' memory in order to allocate 
-the nececessary memory, so normally limits can be reached.
+the necessary memory, so normally limits can be reached.
 
  Other constraints
 -------------------
@@ -296,7 +296,7 @@ the following (from include/linux/if_packet.h):
    - struct tpacket_hdr
    - pad to TPACKET_ALIGNMENT=16
    - struct sockaddr_ll
-   - Gap, chosen so that packet data (Start+tp_net) alignes to 
+   - Gap, chosen so that packet data (Start+tp_net) aligns to 
      TPACKET_ALIGNMENT=16
    - Start+tp_mac: [ Optional MAC header ]
    - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
@@ -311,14 +311,14 @@ the following (from include/linux/if_packet.h):
    tp_frame_size must be a multiple of TPACKET_ALIGNMENT
    tp_frame_nr   must be exactly frames_per_block*tp_block_nr
 
-Note that tp_block_size should be choosed to be a power of two or there will
+Note that tp_block_size should be chosen to be a power of two or there will
 be a waste of memory.
 
 --------------------------------------------------------------------------------
-+ Maping and use of the circular buffer (ring)
++ Mapping and use of the circular buffer (ring)
 --------------------------------------------------------------------------------
 
-The maping of the buffer in the user process is done with the conventional 
+The mapping of the buffer in the user process is done with the conventional 
 mmap function. Even the circular buffer is compound of several physically
 discontiguous blocks of memory, they are contiguous to the user space, hence
 just one call to mmap is needed:
index 18d385c068fc85b8a87deaef82caadd27e4204e6..c8eee23be8c0a43d9c6f998691d44d0296626921 100644 (file)
@@ -7,7 +7,7 @@ Date: 041221
 
 Enable CONFIG_NET_PKTGEN to compile and build pktgen.o either in kernel
 or as module. Module is preferred. insmod pktgen if needed. Once running
-pktgen creates a thread on each CPU where each thread has affinty it's CPU.
+pktgen creates a thread on each CPU where each thread has affinity to its CPU.
 Monitoring and controlling is done via /proc. Easiest to select a suitable 
 a sample script and configure.
 
@@ -18,7 +18,7 @@ root       129  0.3  0.0     0    0 ?        SW    2003 523:20 [pktgen/0]
 root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [pktgen/1]
 
 
-For montoring and control pktgen creates:
+For monitoring and control pktgen creates:
        /proc/net/pktgen/pgctrl
        /proc/net/pktgen/kpktgend_X
         /proc/net/pktgen/ethX
@@ -32,7 +32,7 @@ Running:
 Stopped: eth1 
 Result: OK: max_before_softirq=10000
 
-Most important the devices assigend to thread. Note! A device can only belong 
+Most important the devices assigned to thread. Note! A device can only belong 
 to one thread.
 
 
@@ -147,7 +147,7 @@ Examples:
 Example scripts
 ===============
 
-A collection of small tutorial scripts for pktgen is in expamples dir.
+A collection of small tutorial scripts for pktgen is in examples dir.
 
 pktgen.conf-1-1                  # 1 CPU 1 dev 
 pktgen.conf-1-2                  # 1 CPU 2 dev
index bd528ffbeb4b6c5b0add3dfdd626d2cfd7e843df..4bde53e85f3f02df27191234af82b3ba06b9f7a5 100644 (file)
@@ -126,7 +126,7 @@ However, you may want to set PCI latency timer to 248.
 #setpci -d 17d5:* LATENCY_TIMER=f8
 For detailed description of the PCI registers, please see Xframe User Guide.
 b. Use 2-buffer mode. This results in large performance boost on
-on certain platforms(eg. SGI Altix, IBM xSeries).
+certain platforms(eg. SGI Altix, IBM xSeries).
 c. Ensure Receive Checksum offload is enabled. Use "ethtool -K ethX" command to 
 set/verify this option.
 d. Enable NAPI feature(in kernel configuration Device Drivers ---> Network 
index 7837c53fd5feec94e7351820de4c56c85ac982ad..4e1cc745ec63de85db97de493ebd8ed2365f416c 100644 (file)
@@ -180,7 +180,7 @@ To set the driver parameters in this file, proceed as follows:
 1. Insert a line of the form :
    options sk98lin ...
    For "...", the same syntax is required as described for the command
-   line paramaters of modprobe below.
+   line parameters of modprobe below.
 2. To activate the new parameters, either reboot your computer
    or 
    unload and reload the driver.
@@ -320,7 +320,7 @@ Parameter:    Moderation
 Values:       None, Static, Dynamic
 Default:      None
 
-Interrupt moderation is employed to limit the maxmimum number of interrupts
+Interrupt moderation is employed to limit the maximum number of interrupts
 the driver has to serve. That is, one or more interrupts (which indicate any
 transmit or receive packet to be processed) are queued until the driver 
 processes them. When queued interrupts are to be served, is determined by the
@@ -364,9 +364,9 @@ Parameter:    IntsPerSec
 Values:       30...40000 (interrupts per second)
 Default:      2000
 
-This parameter is only used, if either static or dynamic interrupt moderation
-is used on a network adapter card. Using this paramter if no moderation is
-applied, will lead to no action performed.
+This parameter is only used if either static or dynamic interrupt moderation
+is used on a network adapter card. Using this parameter if no moderation is
+applied will lead to no action performed.
 
 This parameter determines the length of any interrupt moderation interval. 
 Assuming that static interrupt moderation is to be used, an 'IntsPerSec' 
@@ -484,7 +484,7 @@ If any problems occur during the installation process, check the
 following list:
 
 
-Problem:  The SK-98xx adapter can not be found by the driver.
+Problem:  The SK-98xx adapter cannot be found by the driver.
 Solution: In /proc/pci search for the following entry:
              'Ethernet controller: SysKonnect SK-98xx ...'
           If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has 
@@ -497,12 +497,12 @@ Solution: In /proc/pci search for the following entry:
           www.syskonnect.com
           
           Some COMPAQ machines have problems dealing with PCI under Linux.
-          Linux. This problem is described in the 'PCI howto' document
+          This problem is described in the 'PCI howto' document
           (included in some distributions or available from the
           web, e.g. at 'www.linux.org'). 
 
 
-Problem:  Programs such as 'ifconfig' or 'route' can not be found or the 
+Problem:  Programs such as 'ifconfig' or 'route' cannot be found or the 
           error message 'Operation not permitted' is displayed.
 Reason:   You are not logged in as user 'root'.
 Solution: Logout and login as 'root' or change to 'root' via 'su'.
index 3a419ed42f8166a984859849d053c39e6ef76434..abfddf81e34adfe55ae051d3d3c02851323fb2b6 100644 (file)
@@ -81,7 +81,7 @@ Makes my life much easier :-)
 
 If you run into problems during installation, check those items:
 
-Problem:  The FDDI adapter can not be found by the driver.
+Problem:  The FDDI adapter cannot be found by the driver.
 Reason:   Look in /proc/pci for the following entry:
              'FDDI network controller: SysKonnect SK-FDDI-PCI ...'
          If this entry exists, then the FDDI adapter has been
@@ -99,7 +99,7 @@ Reason:   Look in /proc/pci for the following entry:
 
 Problem:  You want to use your computer as a router between
           multiple IP subnetworks (using multiple adapters), but
-         you can not reach computers in other subnetworks.
+         you cannot reach computers in other subnetworks.
 Reason:   Either the router's kernel is not configured for IP
          forwarding or there is a problem with the routing table
          and gateway configuration in at least one of the
index 59cfd95121fbcb4c8ade890c9a9e739d1d6b2f77..2f04c9267f890217c0b7d95900d4b0bb22db0ab4 100644 (file)
@@ -89,7 +89,7 @@ red:  green:  meaning:
 
 -      -       no frame-sync, no signal received, or signal SNAFU.
 -      on      "Everything is OK"
-on     on      Recepion is ok, but the remote end sends Remote Alarm
+on     on      Reception is ok, but the remote end sends Remote Alarm
 on     -       The interface is unconfigured
 
 -----------------------------------------------------------------
@@ -257,12 +257,12 @@ which begin with '//' are the comments.
 // No alarms - Everything OK
 //
 // LOS  - Loss Of Signal - No signal sensed on the input
-// AIS  - Alarm Indication Signal - The remot side sends '11111111'-s, 
+// AIS  - Alarm Indication Signal - The remote side sends '11111111'-s, 
 //     it tells, that there's an error condition, or it's not
 //     initialised.
 // AUXP - Auxiliary Pattern Indication - 01010101.. received.
 // LFA  - Loss of Frame Alignment - no frame sync received.
-// RRA  - Receive Remote Alarm - the remote end's OK, but singnals error cond.
+// RRA  - Receive Remote Alarm - the remote end's OK, but signals error cond.
 // LMFA - Loss of CRC4 Multiframe Alignment - no CRC4 multiframe sync.
 // NMF  - No Multiframe alignment Found after 400 msec - no such alarm using
 //     no-crc4 or crc4 framing, see below.
@@ -364,6 +364,6 @@ Treat them very carefully, these can cause much trouble!
 
        # echo >lbireg 0x1d 0x21
 
-               - Swithing the loop off:
+               - Switching the loop off:
 
        # echo >lbireg 0x1d 0x00
index 4c866f5a0ee4ff9a439519e9c57d446b41603315..9af25b810c1f7ff0e3a76960e8b7beb463363126 100644 (file)
@@ -11,7 +11,7 @@ This driver is rather simple to use. Select Y to Token Ring adapter support
 in the kernel configuration. A choice for SMC Token Ring adapters will
 appear. This drives supports all SMC ISA/MCA adapters. Choose this
 option. I personally recommend compiling the driver as a module (M), but if you
-you would like to compile it staticly answer Y instead.
+you would like to compile it statically answer Y instead.
 
 This driver supports multiple adapters without the need to load multiple copies
 of the driver. You should be able to load up to 7 adapters without any kernel
index 0fa300425575b4600594ba9f9edb017e09c60e2b..0121edc3ba0610e7bca0f76934ea20b581d68290 100644 (file)
@@ -62,7 +62,7 @@ if needed and you will get the expected protocol. If you ask for an
 unknown congestion method, then the sysctl attempt will fail.
 
 If you remove a tcp congestion control module, then you will get the next
-available one. Since reno can not be built as a module, and can not be
+available one. Since reno cannot be built as a module, and cannot be
 deleted, it will always be available.
 
 How the new TCP output machine [nyi] works.
index 179e527b9da1302f311862152eb3cc4622a8ba6a..c169a57bc92584704817e116faa9be02a1f9dde7 100644 (file)
@@ -24,7 +24,7 @@ This driver is rather simple to use. Select Y to Token Ring adapter support
 in the kernel configuration. A choice for SysKonnect Token Ring adapters will
 appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this
 option. I personally recommend compiling the driver as a module (M), but if you
-you would like to compile it staticly answer Y instead.
+you would like to compile it statically answer Y instead.
 
 This driver supports multiple adapters without the need to load multiple copies
 of the driver. You should be able to load up to 7 adapters without any kernel
index 6091e5f6794f90c33d1c031d8fcb0d0114a35587..6356d3faed365634bbbe85172b28abdf472c600b 100644 (file)
@@ -359,13 +359,13 @@ steps you should take:
 
    Eliminate some variables: try different cards, different
    computers, different cables, different ports on the switch/hub,
-   different versions of the kernel or ofthe driver, etc.
+   different versions of the kernel or of the driver, etc.
 
 - OK, it's a driver problem.
 
    You need to generate a report.  Typically this is an email to the
    maintainer and/or linux-net@vger.kernel.org.  The maintainer's
-   email address will be inthe driver source or in the MAINTAINERS file.
+   email address will be in the driver source or in the MAINTAINERS file.
 
 - The contents of your report will vary a lot depending upon the
   problem.  If it's a kernel crash then you should refer to the
index c96897aa08b6b89f9845a131635b69842877a575..0cf6541476342b237e34822338984d8b2426448d 100644 (file)
@@ -148,7 +148,7 @@ NEW IN THIS RELEASE
                for async connections.
 
        o Added the PPPCONFIG utility
-               Used to configure the PPPD dameon for the
+               Used to configure the PPPD daemon for the
                WANPIPE Async PPP and standard serial port.
                The wancfg calls the pppconfig to configure
                the pppd.
@@ -214,7 +214,7 @@ PRODUCT COMPONENTS AND RELATED FILES
 /usr/local/wanrouter/patches/kdrivers:
        Sources of the latest WANPIPE device drivers.
        These are used to UPGRADE the linux kernel to the newest
-       version if the kernel source has already been pathced with
+       version if the kernel source has already been patched with
        WANPIPE drivers.
 
 /usr/local/wanrouter/samples:
@@ -350,7 +350,7 @@ REVISION HISTORY
                                 Available as a patch.                 
 
 2.0.6   Aug 17, 1999           Increased debugging in statup scripts
-                               Fixed insallation bugs from 2.0.5
+                               Fixed installation bugs from 2.0.5
                                Kernel patch works for both 2.2.10 and 2.2.11 kernels.
                                There is no functional difference between the two packages         
 
@@ -434,11 +434,11 @@ beta3-2.1.4 Jul 2000              o X25 M_BIT Problem fix.
                                  change. 
          
 beta1-2.1.5    Nov 15 2000
-                               o Fixed the MulitPort PPP Support for kernels 2.2.16 and above.
+                               o Fixed the MultiPort PPP Support for kernels 2.2.16 and above.
                                  2.2.X kernels only
 
                                o Secured the driver UDP debugging calls
-                                       - All illegal netowrk debugging calls are reported to
+                                       - All illegal network debugging calls are reported to
                                          the log.
                                        - Defined a set of allowed commands, all other denied.
                                        
@@ -451,7 +451,7 @@ beta1-2.1.5         Nov 15 2000
 
                                o Keyboard Led Monitor/Debugger
                                        - A new utilty /usr/sbin/wpkbdmon uses keyboard leds
-                                         to convey operatinal statistic information of the 
+                                         to convey operational statistic information of the 
                                          Sangoma WANPIPE cards.
                                        NUM_LOCK    = Line State  (On=connected,    Off=disconnected)
                                        CAPS_LOCK   = Tx data     (On=transmitting, Off=no tx data)
@@ -470,7 +470,7 @@ beta1-2.1.5         Nov 15 2000
                                o Fixed the Frame Relay and Chdlc network interfaces so they are
                                  compatible with libpcap libraries.  Meaning, tcpdump, snort,
                                  ethereal, and all other packet sniffers and debuggers work on
-                                 all WANPIPE netowrk interfaces.
+                                 all WANPIPE network interfaces.
                                        - Set the network interface encoding type to ARPHRD_PPP.
                                          This tell the sniffers that data obtained from the
                                          network interface is in pure IP format.
@@ -570,7 +570,7 @@ bata1-2.2.1 Feb 09 2001
 
                                Option to COMPILE WANPIPE modules against the currently 
                                running kernel, thus no need for manual kernel and module
-                               re-compilatin.
+                               re-compilation.
                        
                        o Updates and Bug Fixes to wancfg utility.
 
index 3cc953cb288ff8887fa8123b68a60288320dc5ca..719f9a9d60c0a4a5c9668608eb3f588b130835ed 100644 (file)
@@ -11,7 +11,7 @@ Updated 2006 by Horms <horms@verge.net.au>
 In order to use a diskless system, such as an X-terminal or printer server
 for example, it is necessary for the root filesystem to be present on a
 non-disk device. This may be an initramfs (see Documentation/filesystems/
-ramfs-rootfs-initramfs.txt), a ramdisk (see Documenation/initrd.txt) or a
+ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a
 filesystem mounted via NFS. The following text describes on how to use NFS
 for the root filesystem. For the rest of this text 'client' means the
 diskless system, and 'server' means the NFS server.
index 634d3e5b575691baaa55167c019cea3875c4920f..6650af43252301c1bdbbc4adc8b0da815f29e422 100644 (file)
@@ -172,7 +172,7 @@ is STEP 6 (Permanent Failure).
 >>> a value of 0xff on read, and writes will be dropped. If the device
 >>> driver attempts more than 10K I/O's to a frozen adapter, it will
 >>> assume that the device driver has gone into an infinite loop, and
->>> it will panic the the kernel. There doesn't seem to be any other
+>>> it will panic the kernel. There doesn't seem to be any other
 >>> way of stopping a device driver that insists on spinning on I/O.
 
 STEP 2: MMIO Enabled
index 5d61dacd21f6dca7e0ee84c1bcd9132f1b60d553..9a5bc8651c2923c619b168c1719f1e25e381e368 100644 (file)
@@ -118,4 +118,4 @@ properties of futexes, and all four combinations are possible: futex,
 robust-futex, PI-futex, robust+PI-futex.
 
 More details about priority inheritance can be found in
-Documentation/rtmutex.txt.
+Documentation/rt-mutex.txt.
index 79c0f32a760e98ac60e1d8ca57f44cbcb3c33b99..da8589a0e07df08b77ae15c5bb83f7800f9b2bdf 100644 (file)
@@ -18,10 +18,10 @@ enabled by default).  If a working ACPI implementation is found, the
 ACPI driver will override and disable APM, otherwise the APM driver
 will be used.
 
-No sorry, you can not have both ACPI and APM enabled and running at
+No, sorry, you cannot have both ACPI and APM enabled and running at
 once.  Some people with broken ACPI or broken APM implementations
 would like to use both to get a full set of working features, but you
-simply can not mix and match the two.  Only one power management
+simply cannot mix and match the two.  Only one power management
 interface can be in control of the machine at once.  Think about it..
 
 User-space Daemons
@@ -106,7 +106,7 @@ void pm_unregister_all(pm_callback cback);
  *
  * Returns: 0 if the request is successful
  *          EINVAL if the request is not supported
- *          EBUSY if the device is now busy and can not handle the request
+ *          EBUSY if the device is now busy and cannot handle the request
  *          ENOMEM if the device was unable to handle the request due to memory
  *          
  * Details: The device request callback will be called before the
index 9529c9c9fd59fe69d8d960b05a9522e7ba0bbaac..9ff966bf76e65be0fc6281d879d673ce0f861143 100644 (file)
@@ -222,7 +222,7 @@ static struct pnp_driver serial_pnp_driver = {
        .remove         = serial_pnp_remove,
 };
 
-* name and id_table can not be NULL.
+* name and id_table cannot be NULL.
 
 4.) register the driver
 ex:
index 73fc87e5dc382013207ccbf5c2989eb0e1240abf..24edf25b3bb7f17179f23ca644bd3f341943b19a 100644 (file)
@@ -326,7 +326,7 @@ A reference implementation
 
 This is a typical implementation. Drivers can slightly change the order
 of the operations in the implementation, ignore some operations or add
-more deriver specific operations in it, but drivers should do something like
+more driver specific operations in it, but drivers should do something like
 this on the whole.
 
 5. Resources
index 823b2cf6e3dcf5a1cbca775cf827dc959b0af131..9ea2208b43b5f712c74b3e9d40762fd47a1a7706 100644 (file)
@@ -156,7 +156,7 @@ instead set the PF_NOFREEZE process flag when creating the thread (and
 be very carefull).
 
 
-Q: What is the difference between between "platform", "shutdown" and
+Q: What is the difference between "platform", "shutdown" and
 "firmware" in /sys/power/disk?
 
 A:
@@ -175,8 +175,8 @@ reliable.
 Q: I do not understand why you have such strong objections to idea of
 selective suspend.
 
-A: Do selective suspend during runtime power managment, that's okay. But
-its useless for suspend-to-disk. (And I do not see how you could use
+A: Do selective suspend during runtime power management, that's okay. But
+it's useless for suspend-to-disk. (And I do not see how you could use
 it for suspend-to-ram, I hope you do not want that).
 
 Lets see, so you suggest to
@@ -211,7 +211,7 @@ slowness may not matter to you. It can always be fixed later.
 For devices like disk it does matter, you do not want to spindown for
 FREEZE.
 
-Q: After resuming, system is paging heavilly, leading to very bad interactivity.
+Q: After resuming, system is paging heavily, leading to very bad interactivity.
 
 A: Try running
 
index c6d58d3da133f2db8df7ae7802d2af25822b7493..3b26bb502a4a608d54f5fd7940d376e231f2fb4e 100644 (file)
@@ -9,7 +9,7 @@ If you want to trick swsusp/S3 into working, you might want to try:
 
 * turn off APIC and preempt
 
-* use ext2. At least it has working fsck. [If something seemes to go
+* use ext2. At least it has working fsck. [If something seems to go
   wrong, force fsck when you have a chance]
 
 * turn off modules
index 94058220aaf0b74aeaa1df00420da7e8283d7e8f..64755e9285dbfe9236916bc7aca819b9d41f908e 100644 (file)
@@ -91,7 +91,7 @@ unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are
 still frozen when the device is being closed).
 
 Currently it is assumed that the userland utilities reading/writing the
-snapshot image from/to the kernel will use a swap parition, called the resume
+snapshot image from/to the kernel will use a swap partition, called the resume
 partition, as storage space.  However, this is not really required, as they
 can use, for example, a special (blank) suspend partition or a file on a partition
 that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and mounted afterwards.
index d859faa3a463235b40a7e3f90c263d4e28da6918..2b358498d095b59d8ddf950b1c1ec109c2c6e7d8 100644 (file)
@@ -16,7 +16,7 @@ problem for S1 standby, because hardware should retain its state over
 that.
 
 We either have to run video BIOS during early resume, or interpret it
-using vbetool later, or maybe nothing is neccessary on particular
+using vbetool later, or maybe nothing is necessary on particular
 system because video state is preserved. Unfortunately different
 methods work on different systems, and no known method suits all of
 them.
index b57e7da7897667b2e2702944cae029677219e7e6..27b457c09729e29bafaade3bc240bfaebf755e01 100644 (file)
@@ -145,7 +145,7 @@ it with special cases.
                 in case you are entering the kernel with MMU enabled
                 and a non-1:1 mapping.
 
-                r5 : NULL (as to differenciate with method a)
+                r5 : NULL (as to differentiate with method a)
 
         Note about SMP entry: Either your firmware puts your other
         CPUs in some sleep loop or spin loop in ROM where you can get
@@ -245,7 +245,7 @@ the block to RAM before passing it to the kernel.
 ---------
 
    The kernel is entered with r3 pointing to an area of memory that is
-   roughtly described in include/asm-powerpc/prom.h by the structure
+   roughly described in include/asm-powerpc/prom.h by the structure
    boot_param_header:
 
 struct boot_param_header {
@@ -335,7 +335,7 @@ struct boot_param_header {
      "compact" format for the tree itself that is however not backward
      compatible. You should always generate a structure of the highest
      version defined at the time of your implementation. Currently
-     that is version 16, unless you explicitely aim at being backward
+     that is version 16, unless you explicitly aim at being backward
      compatible.
 
    - last_comp_version
@@ -418,9 +418,9 @@ zero terminated string and is mandatory for version 1 to 3 of the
 format definition (as it is in Open Firmware). Version 0x10 makes it
 optional as it can generate it from the unit name defined below.
 
-There is also a "unit name" that is used to differenciate nodes with
+There is also a "unit name" that is used to differentiate nodes with
 the same name at the same level, it is usually made of the node
-name's, the "@" sign, and a "unit address", which definition is
+names, the "@" sign, and a "unit address", which definition is
 specific to the bus type the node sits on.
 
 The unit name doesn't exist as a property per-se but is included in
@@ -550,11 +550,11 @@ Here's the basic structure of a single node:
      * [child nodes if any]
      * token OF_DT_END_NODE (that is 0x00000002)
 
-So the node content can be summmarised as a start token, a full path,
-a list of properties, a list of child node and an end token. Every
+So the node content can be summarised as a start token, a full path,
+a list of properties, a list of child nodes, and an end token. Every
 child node is a full node structure itself as defined above.
 
-4) Device tree 'strings" block
+4) Device tree "strings" block
 
 In order to save space, property names, which are generally redundant,
 are stored separately in the "strings" block. This block is simply the
@@ -573,7 +573,7 @@ implementation of Open Firmware or an implementation compatible with
 the Open Firmware client interface, those properties will be created
 by the trampoline code in the kernel's prom_init() file. For example,
 that's where you'll have to add code to detect your board model and
-set the platform number. However, when using the flatenned device-tree
+set the platform number. However, when using the flattened device-tree
 entry point, there is no prom_init() pass, and thus you have to
 provide those properties yourself.
 
@@ -630,12 +630,11 @@ like address space bits, you'll have to add a bus translator to the
 prom_parse.c file of the recent kernels for your bus type.
 
 The "reg" property only defines addresses and sizes (if #size-cells
-is
-non-0) within a given bus. In order to translate addresses upward
+is non-0) within a given bus. In order to translate addresses upward
 (that is into parent bus addresses, and possibly into cpu physical
 addresses), all busses must contain a "ranges" property. If the
 "ranges" property is missing at a given level, it's assumed that
-translation isn't possible. The format of the "ranges" proprety for a
+translation isn't possible. The format of the "ranges" property for a
 bus is a list of:
 
        bus address, parent bus address, size
@@ -689,7 +688,7 @@ is present).
 4) Note about node and property names and character set
 -------------------------------------------------------
 
-While open firmware provides more flexibe usage of 8859-1, this
+While open firmware provides more flexible usage of 8859-1, this
 specification enforces more strict rules. Nodes and properties should
 be comprised only of ASCII characters 'a' to 'z', '0' to
 '9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally
@@ -732,12 +731,12 @@ address which can extend beyond that limit.
       that typically get driven by the same platform code in the
       kernel, you would use a different "model" property but put a
       value in "compatible". The kernel doesn't directly use that
-      value (see /chosen/linux,platform for how the kernel choses a
+      value (see /chosen/linux,platform for how the kernel chooses a
       platform type) but it is generally useful.
 
   The root node is also generally where you add additional properties
   specific to your board like the serial number if any, that sort of
-  thing. it is recommended that if you add any "custom" property whose
+  thing. It is recommended that if you add any "custom" property whose
   name may clash with standard defined ones, you prefix them with your
   vendor name and a comma.
 
@@ -817,7 +816,7 @@ address which can extend beyond that limit.
       your board. It's a list of addresses/sizes concatenated
       together, with the number of cells of each defined by the
       #address-cells and #size-cells of the root node. For example,
-      with both of these properties beeing 2 like in the example given
+      with both of these properties being 2 like in the example given
       earlier, a 970 based machine with 6Gb of RAM could typically
       have a "reg" property here that looks like:
 
@@ -970,7 +969,7 @@ device-tree in another format. The currently supported formats are:
      - "asm": assembly language file. This is a file that can be
        sourced by gas to generate a device-tree "blob". That file can
        then simply be added to your Makefile. Additionally, the
-       assembly file exports some symbols that can be use
+       assembly file exports some symbols that can be used.
 
 
 The syntax of the dtc tool is
@@ -984,10 +983,10 @@ generated. Supported versions are 1,2,3 and 16. The default is
 currently version 3 but that may change in the future to version 16.
 
 Additionally, dtc performs various sanity checks on the tree, like the
-uniqueness of linux,phandle properties, validity of strings, etc...
+uniqueness of linux, phandle properties, validity of strings, etc...
 
 The format of the .dts "source" file is "C" like, supports C and C++
-style commments.
+style comments.
 
 / {
 }
@@ -1069,13 +1068,13 @@ while all this has been defined and implemented.
     around. It contains no internal offsets or pointers for this
     purpose.
 
-  - An example of code for iterating nodes & retreiving properties
+  - An example of code for iterating nodes & retrieving properties
     directly from the flattened tree format can be found in the kernel
     file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function,
-    it's usage in early_init_devtree(), and the corresponding various
+    its usage in early_init_devtree(), and the corresponding various
     early_init_dt_scan_*() callbacks. That code can be re-used in a
     GPL bootloader, and as the author of that code, I would be happy
-    do discuss possible free licencing to any vendor who wishes to
+    to discuss possible free licencing to any vendor who wishes to
     integrate all or part of this code into a non-GPL bootloader.
 
 
index 3764dd4b12cbac8f1d5a224faca4f2f5894ed889..4530d1bf0286f68a5642f8ad6e99096447e14aa4 100644 (file)
@@ -90,7 +90,7 @@ EEH-isolated, there is a firmware call it can make to determine if
 this is the case. If so, then the device driver should put itself
 into a consistent state (given that it won't be able to complete any
 pending work) and start recovery of the card.  Recovery normally
-would consist of reseting the PCI device (holding the PCI #RST
+would consist of resetting the PCI device (holding the PCI #RST
 line high for two seconds), followed by setting up the device
 config space (the base address registers (BAR's), latency timer,
 cache line size, interrupt line, and so on).  This is followed by a
@@ -116,7 +116,7 @@ At this time, a generic EEH recovery mechanism has been implemented,
 so that individual device drivers do not need to be modified to support
 EEH recovery.  This generic mechanism piggy-backs on the PCI hotplug
 infrastructure,  and percolates events up through the userspace/udev
-infrastructure.  Followiing is a detailed description of how this is
+infrastructure.  Following is a detailed description of how this is
 accomplished.
 
 EEH must be enabled in the PHB's very early during the boot process,
index 1e38166f4e54b1d83cf5cb86c68394826c2e5fa9..f93462c5db25f7828a17897424604bf7d84e3ea2 100644 (file)
@@ -259,7 +259,7 @@ This index of '2' means that in order to connect to vty-server adapter
 
 It should be noted that due to the system hotplug I/O capabilities of a
 system the /dev/hvcs* entry that interacts with a particular vty-server
-adapter is not guarenteed to remain the same across system reboots.  Look
+adapter is not guaranteed to remain the same across system reboots.  Look
 in the Q & A section for more on this issue.
 
 ---------------------------------------------------------------------------
index 2fbb0c49bc5b6d8e4389dd9daa7fb4bbf59a6d17..3aa68f9a117b19cac846aabd769d53d46f657e82 100644 (file)
@@ -88,7 +88,7 @@ path which is not desirable. Hence, we do not optimize the height of the
 heap-and-size indexed overflow-sub-trees using prio_tree->index_bits.
 Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits
 of size_index. This may lead to skewed sub-trees because most of the
-higher significant bits of the size_index are likely to be be 0 (zero). In
+higher significant bits of the size_index are likely to be 0 (zero). In
 the example above, all 3 overflow-sub-trees are skewed. This may marginally
 affect the performance. However, processes rarely map many vmas with the
 same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally
index a1067800445192c5de70b16a62ac4571c34734f1..1d8582990435b55579c8396507c875121a411ad7 100644 (file)
@@ -97,7 +97,7 @@ a range of I/O addresses for it to use. The first RocketPort card
 requires a 68-byte contiguous block of I/O addresses, starting at one
 of the following: 0x100h, 0x140h, 0x180h, 0x200h, 0x240h, 0x280h,
 0x300h, 0x340h, 0x380h.  This I/O address must be reflected in the DIP
-switiches of *all* of the Rocketport cards.
+switches of *all* of the Rocketport cards.
 
 The second, third, and fourth RocketPort cards require a 64-byte
 contiguous block of I/O addresses, starting at one of the following
@@ -107,7 +107,7 @@ second, third, and fourth Rocketport cards (if present) are set via
 software control.  The DIP switch settings for the I/O address must be
 set to the value of the first Rocketport cards.
 
-In order to destinguish each of the card from the others, each card
+In order to distinguish each of the card from the others, each card
 must have a unique board ID set on the dip switches.  The first
 Rocketport board must be set with the DIP switches corresponding to
 the first board, the second board must be set with the DIP switches
@@ -120,7 +120,7 @@ conflict with any other cards in the system, including other
 RocketPort cards.  Below, you will find a list of commonly used I/O
 address ranges which may be in use by other devices in your system.
 On a Linux system, "cat /proc/ioports" will also be helpful in
-identifying what I/O addresses are being used by devics on your
+identifying what I/O addresses are being used by devices on your
 system.
 
 Remember, the FIRST RocketPort uses 68 I/O addresses.  So, if you set it
index 5f757c8cf979524b8fc8be321b77660a97cdc941..8a382bea6808ed687fd1bacd8f3015e671f6bc1b 100644 (file)
@@ -24,7 +24,7 @@ The common code handles such things as:
    - general cache lookup with correct locking
    - supporting 'NEGATIVE' as well as positive entries
    - allowing an EXPIRED time on cache items, and removing
-     items after they expire, and are no longe in-use.
+     items after they expire, and are no longer in-use.
    - making requests to user-space to fill in cache entries
    - allowing user-space to directly set entries in the cache
    - delaying RPC requests that depend on as-yet incomplete
@@ -53,7 +53,7 @@ Creating a Cache
                structure
        void cache_put(struct kref *)
                This is called when the last reference to an item is
-               is dropped.  The pointer passed is to the 'ref' field
+               dropped.  The pointer passed is to the 'ref' field
                in the cache_head.  cache_put should release any
                references create by 'cache_init' and, if CACHE_VALID
                is set, any references created by cache_update.
index 0a044e647d2d9a9e96d960f538f381d975e4d056..7a5c73a7ed7f400694a8d97f0b43cfbef75fef67 100644 (file)
@@ -111,9 +111,7 @@ Here are the installation steps in detail:
        config3270.sh.  Inspect the output script it produces,
        /tmp/mkdev3270, and then run that script.  This will create the
        necessary character special device files and make the necessary
-       changes to /etc/inittab.  If you have selected DEVFS, the driver
-       itself creates the device files, and /tmp/mkdev3270 only changes
-       /etc/inittab.
+       changes to /etc/inittab.
 
        Then notify /sbin/init that /etc/inittab has changed, by issuing
        the telinit command with the q operand:
index 844c03fe7921d62539b63c7748bfc120fb7b87e1..4dd25ee549e9d14aa1b431e5cabd44c2e320a8fd 100644 (file)
@@ -8,8 +8,8 @@
 Overview of Document:
 =====================
 This document is intended to give an good overview of how to debug 
-Linux for s/390 & z/Architecture it isn't intended as a complete reference & not a
-tutorial on the fundamentals of C & assembly, it dosen't go into
+Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a
+tutorial on the fundamentals of C & assembly. It doesn't go into
 390 IO in any detail. It is intended to complement the documents in the
 reference section below & any other worthwhile references you get.
 
@@ -88,7 +88,7 @@ s/390 z/Architecture
 0       0     Reserved ( must be 0 ) otherwise specification exception occurs.
 
 1       1     Program Event Recording 1 PER enabled, 
-             PER is used to facilititate debugging e.g. single stepping.
+             PER is used to facilitate debugging e.g. single stepping.
 
 2-4    2-4    Reserved ( must be 0 ). 
 
@@ -163,7 +163,7 @@ s/390 z/Architecture
                 1         1        64 bit
 
 32             1=31 bit addressing mode 0=24 bit addressing mode (for backward 
-               compatibility ), linux always runs with this bit set to 1
+               compatibility), linux always runs with this bit set to 1
 
 33-64          Instruction address.
       33-63    Reserved must be 0
@@ -188,7 +188,7 @@ Bytes 0-512 ( 200 hex ) on s/390 & 0-512,4096-4544,4604-5119 currently on z/Arch
 are used by the processor itself for holding such information as exception indications & 
 entry points for exceptions.
 Bytes after 0xc00 hex are used by linux for per processor globals on s/390 & z/Architecture 
-( there is a gap on z/Architecure too currently between 0xc00 & 1000 which linux uses ).
+( there is a gap on z/Architecture too currently between 0xc00 & 1000 which linux uses ).
 The closest thing to this on traditional architectures is the interrupt
 vector table. This is a good thing & does simplify some of the kernel coding
 however it means that we now cannot catch stray NULL pointers in the
@@ -239,7 +239,7 @@ they go to 64 Bit.
 
 On 390 our limitations & strengths make us slightly different.
 For backward compatibility we are only allowed use 31 bits (2GB)
-of our 32 bit addresses,however, we use entirely separate address 
+of our 32 bit addresses, however, we use entirely separate address 
 spaces for the user & kernel.
 
 This means we can support 2GB of non Extended RAM on s/390, & more
@@ -317,9 +317,9 @@ Each process/thread under Linux for S390 has its own kernel task_struct
 defined in linux/include/linux/sched.h
 The S390 on initialisation & resuming of a process on a cpu sets
 the __LC_KERNEL_STACK variable in the spare prefix area for this cpu
-( which we use for per processor globals).
+(which we use for per-processor globals).
 
-The kernel stack pointer is intimately tied with the task stucture for
+The kernel stack pointer is intimately tied with the task structure for
 each processor as follows.
 
                       s/390
@@ -354,7 +354,7 @@ static inline struct task_struct * get_current(void)
 }
 
 i.e. just anding the current kernel stack pointer with the mask -8192.
-Thankfully because Linux dosen't have support for nested IO interrupts
+Thankfully because Linux doesn't have support for nested IO interrupts
 & our devices have large buffers can survive interrupts being shut for 
 short amounts of time we don't need a separate stack for interrupts.
 
@@ -366,8 +366,8 @@ Register Usage & Stackframes on Linux for s/390 & z/Architecture
 Overview:
 ---------
 This is the code that gcc produces at the top & the bottom of
-each function, it usually is fairly consistent & similar from 
-function to function & if you know its layout you can probalby
+each function. It usually is fairly consistent & similar from 
+function to function & if you know its layout you can probably
 make some headway in finding the ultimate cause of a problem
 after a crash without a source level debugger.
 
@@ -394,7 +394,7 @@ i.e they aren't in registers & they aren't static.
 back-chain:
 This is a pointer to the stack pointer before entering a
 framed functions ( see frameless function ) prologue got by 
-deferencing the address of the current stack pointer,
+dereferencing the address of the current stack pointer,
  i.e. got by accessing the 32 bit value at the stack pointers
 current location.
 
@@ -724,7 +724,7 @@ This is useful for debugging because
 1) You can double check whether the files you expect to be included are the ones
 that are being included ( e.g. double check that you aren't going to the i386 asm directory ).
 2) Check that macro definitions aren't clashing with typedefs,
-3) Check that definitons aren't being used before they are being included.
+3) Check that definitions aren't being used before they are being included.
 4) Helps put the line emitting the error under the microscope if it contains macros.
 
 For convenience the Linux kernel's makefile will do preprocessing automatically for you
@@ -840,12 +840,11 @@ using the strip command to make it a more reasonable size to boot it.
 
 A source/assembly mixed dump of the kernel can be done with the line
 objdump --source vmlinux > vmlinux.lst
-Also if the file isn't compiled -g this will output as much debugging information
-as it can ( e.g. function names ), however, this is very slow as it spends lots
-of time searching for debugging info, the following self explanitory line should be used 
-instead if the code isn't compiled -g.
+Also, if the file isn't compiled -g, this will output as much debugging information
+as it can (e.g. function names). This is very slow as it spends lots
+of time searching for debugging info. The following self explanatory line should be used 
+instead if the code isn't compiled -g, as it is much faster:
 objdump --disassemble-all --syms vmlinux > vmlinux.lst  
-as it is much faster
 
 As hard drive space is valuble most of us use the following approach.
 1) Look at the emitted psw on the console to find the crash address in the kernel.
@@ -861,7 +860,7 @@ Linux source tree.
 6) rm /arch/s390/kernel/signal.o
 7) make /arch/s390/kernel/signal.o
 8) watch the gcc command line emitted
-9) type it in again or alernatively cut & paste it on the console adding the -g option.
+9) type it in again or alternatively cut & paste it on the console adding the -g option.
 10) objdump --source arch/s390/kernel/signal.o > signal.lst
 This will output the source & the assembly intermixed, as the snippet below shows
 This will unfortunately output addresses which aren't the same
@@ -913,8 +912,8 @@ If you wanted to know does ping work but didn't have the source
 strace ping -c 1 127.0.0.1  
 & then look at the man pages for each of the syscalls below,
 ( In fact this is sometimes easier than looking at some spagetti
-source which conditionally compiles for several architectures )
-Not everything that it throws out needs to make sense immeadiately
+source which conditionally compiles for several architectures ).
+Not everything that it throws out needs to make sense immediately.
 
 Just looking quickly you can see that it is making up a RAW socket
 for the ICMP protocol.
@@ -974,8 +973,9 @@ through the pipe for each line containing the string open.
 
 Example 3
 ---------
-Getting sophistocated
-telnetd crashes on & I don't know why
+Getting sophisticated
+telnetd crashes & I don't know why
+
 Steps
 -----
 1) Replace the following line in /etc/inetd.conf
@@ -1085,8 +1085,7 @@ Notes
 -----
 Addresses & values in the VM debugger are always hex never decimal
 Address ranges are of the format <HexValue1>-<HexValue2> or <HexValue1>.<HexValue2> 
-e.g. The address range  0x2000 to 0x3000 can be described described as
-2000-3000 or 2000.1000
+e.g. The address range  0x2000 to 0x3000 can be described as 2000-3000 or 2000.1000
 
 The VM Debugger is case insensitive.
 
@@ -1311,7 +1310,7 @@ for finding out when a particular variable changes.
 
 An alternative way of finding the STD of a currently running process 
 is to do the following, ( this method is more complex but
-could be quite convient if you aren't updating the kernel much &
+could be quite convenient if you aren't updating the kernel much &
 so your kernel structures will stay constant for a reasonable period of
 time ).
 
@@ -1413,7 +1412,7 @@ SMP Specific commands
 To find out how many cpus you have
 Q CPUS displays all the CPU's available to your virtual machine
 To find the cpu that the current cpu VM debugger commands are being directed at do
-Q CPU to change the current cpu cpu VM debugger commands are being directed at do
+Q CPU to change the current cpu VM debugger commands are being directed at do
 CPU <desired cpu no>
 
 On a SMP guest issue a command to all CPUs try prefixing the command with cpu all.
@@ -1674,8 +1673,8 @@ channel is idle & the second for device end ( secondary status ) sometimes you g
 concurrently, you check how the IO went on by issuing a TEST SUBCHANNEL at each interrupt,
 from which you receive an Interruption response block (IRB). If you get channel & device end 
 status in the IRB without channel checks etc. your IO probably went okay. If you didn't you
-probably need a doctorto examine the IRB & extended status word etc.
-If an error occurs more sophistocated control units have a facitity known as
+probably need a doctor to examine the IRB & extended status word etc.
+If an error occurs, more sophistocated control units have a facitity known as
 concurrent sense this means that if an error occurs Extended sense information will
 be presented in the Extended status word in the IRB if not you have to issue a
 subsequent SENSE CCW command after the test subchannel. 
@@ -1704,7 +1703,7 @@ concentrate on data processing.
 IOP's can use one or more links ( known as channel paths ) to talk to each 
 IO device. It first checks for path availability & chooses an available one,
 then starts ( & sometimes terminates IO ).
-There are two types of channel path ESCON & the Paralell IO interface.
+There are two types of channel path: ESCON & the Parallel IO interface.
 
 IO devices are attached to control units, control units provide the
 logic to interface the channel paths & channel path IO protocols to 
@@ -1743,11 +1742,11 @@ controllers or a control unit which connects to 1000 3270 terminals ).
 
 The 390 IO systems come in 2 flavours the current 390 machines support both
 
-The Older 360 & 370 Interface,sometimes called the paralell I/O interface,
+The Older 360 & 370 Interface,sometimes called the Parallel I/O interface,
 sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers
 Interface (OEMI).
 
-This byte wide paralell channel path/bus has parity & data on the "Bus" cable 
+This byte wide Parallel channel path/bus has parity & data on the "Bus" cable 
 & control lines on the "Tag" cable. These can operate in byte multiplex mode for
 sharing between several slow devices or burst mode & monopolize the channel for the
 whole burst. Upto 256 devices can be addressed  on one of these cables. These cables are
@@ -1777,7 +1776,7 @@ Consoles 3270 & 3215 ( a teletype emulated under linux for a line mode console )
 DASD's direct access storage devices ( otherwise known as hard disks ).
 Tape Drives.
 CTC ( Channel to Channel Adapters ),
-ESCON or Paralell Cables used as a very high speed serial link
+ESCON or Parallel Cables used as a very high speed serial link
 between 2 machines. We use 2 cables under linux to do a bi-directional serial link.
 
 
@@ -1803,8 +1802,8 @@ OSA  7C09 ON OSA   7C09 SUBCHANNEL = 0001
 OSA  7C14 ON OSA   7C14 SUBCHANNEL = 0002
 OSA  7C15 ON OSA   7C15 SUBCHANNEL = 0003
 
-If you have a guest with certain priviliges you may be able to see devices
-which don't belong to you to avoid this do add the option V.
+If you have a guest with certain privileges you may be able to see devices
+which don't belong to you. To avoid this, add the option V.
 e.g.
 Q V OSA
 
@@ -1837,7 +1836,7 @@ RDRLIST
 RECEIVE / LOG TXT A1 ( replace
 8)
 filel & press F11 to look at it
-You should see someting like.
+You should see something like:
 
 00020942' SSCH  B2334000    0048813C    CC 0    SCH 0000    DEV 7C08
           CPA 000FFDF0   PARM 00E2C9C4    KEY 0  FPI C0  LPM 80
@@ -1916,7 +1915,7 @@ Assembly
 --------
 info registers: displays registers other than floating point.
 info all-registers: displays floating points as well.
-disassemble: dissassembles
+disassemble: disassembles
 e.g.
 disassemble without parameters will disassemble the current function
 disassemble $pc $pc+10 
@@ -1935,7 +1934,7 @@ undisplay : undo's display's
 
 info breakpoints: shows all current breakpoints
 
-info stack: shows stack back trace ( if this dosent work too well, I'll show you the
+info stack: shows stack back trace ( if this doesn't work too well, I'll show you the
 stacktrace by hand below ).
 
 info locals: displays local variables.
@@ -2045,13 +2044,13 @@ what gdb does when the victim receives certain signals.
 list:
 e.g.
 list lists current function source
-list 1,10 list first 10 lines of curret file.
+list 1,10 list first 10 lines of current file.
 list test.c:1,10
 
 
 directory:
 Adds directories to be searched for source if gdb cannot find the source.
-(note it is a bit sensititive about slashes 
+(note it is a bit sensititive about slashes) 
 e.g. To add the root of the filesystem to the searchpath do
 directory //
 
@@ -2123,9 +2122,9 @@ p/x (*(**$sp+56))&0x7fffffff
 
 Disassembling instructions without debug info
 ---------------------------------------------
-gdb typically compains if there is a lack of debugging
-symbols in  the disassemble command with 
-"No function contains specified address." to get around
+gdb typically complains if there is a lack of debugging
+symbols in the disassemble command with 
+"No function contains specified address." To get around
 this do 
 x/<number lines to disassemble>xi <address>
 e.g.
@@ -2184,7 +2183,7 @@ ps -aux | grep gdb
 kill -SIGSEGV <gdb's pid>
 or alternatively use killall -SIGSEGV gdb if you have the killall command.
 Now look at the core dump.
-./gdb ./gdb core
+./gdb core
 Displays the following
 GNU gdb 4.18
 Copyright 1998 Free Software Foundation, Inc.
@@ -2316,7 +2315,7 @@ Showing us the shared libraries init uses where they are in memory
 /proc/1/mem is the current running processes memory which you
 can read & write to like a file.
 strace uses this sometimes as it is a bit faster than the
-rather inefficent ptrace interface for peeking at DATA.
+rather inefficient ptrace interface for peeking at DATA.
 
 
 cat status 
@@ -2446,7 +2445,7 @@ displays the following lines as it executes them.
 + RELSTATUS=release
 + MACHTYPE=i586-pc-linux-gnu   
 
-perl -d <scriptname> runs the perlscript in a fully intercative debugger
+perl -d <scriptname> runs the perlscript in a fully interactive debugger
 <like gdb>.
 Type 'h' in the debugger for help.
 
@@ -2477,7 +2476,7 @@ Lcrash is a perfectly normal program,however, it requires 2
 additional files, Kerntypes which is built using a patch to the 
 linux kernel sources in the linux root directory & the System.map.
 
-Kerntypes is an an objectfile whose sole purpose in life
+Kerntypes is an objectfile whose sole purpose in life
 is to provide stabs debug info to lcrash, to do this
 Kerntypes is built from kerntypes.c which just includes the most commonly
 referenced header files used when debugging, lcrash can then read the
index f0be389c7116934b6c1e43b97d70dab486aedf2a..d80e5733827d2ae0ac58a82f166baf08a7a7daef 100644 (file)
@@ -133,7 +133,7 @@ determine the device driver owning the device that raised the interrupt.
 In order not to introduce a new I/O concept to the common Linux code,
 Linux/390 preserves the IRQ concept and semantically maps the ESA/390
 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
-different IRQs, uniquely representig a single device each.
+different IRQs, uniquely representing a single device each.
 
 Up to kernel 2.4, Linux/390 used to provide interfaces via the IRQ (subchannel).
 For internal use of the common I/O layer, these are still there. However, 
@@ -143,7 +143,7 @@ During its startup the Linux/390 system checks for peripheral devices. Each
 of those devices is uniquely defined by a so called subchannel by the ESA/390
 channel subsystem. While the subchannel numbers are system generated, each
 subchannel also takes a user defined attribute, the so called device number.
-Both subchannel number and device number can not exceed 65535. During driverfs
+Both subchannel number and device number cannot exceed 65535. During driverfs
 initialisation, the information about control unit type and device types that 
 imply specific I/O commands (channel command words - CCWs) in order to operate
 the device are gathered. Device drivers can retrieve this set of hardware
@@ -177,11 +177,11 @@ This routine returns the characteristics for the device specified.
 The function is meant to be called with an irq handler in place; that is,
 at earliest during set_online() processing.
 
-While the request is procesed synchronously, the device interrupt
+While the request is processed synchronously, the device interrupt
 handler is called for final ending status. In case of error situations the
 interrupt handler may recover appropriately. The device irq handler can
 recognize the corresponding interrupts by the interruption parameter be
-0x00524443.The ccw_device must not be locked prior to calling read_dev_chars().
+0x00524443. The ccw_device must not be locked prior to calling read_dev_chars().
 
 The function may be called enabled or disabled.
 
@@ -325,7 +325,7 @@ with the following CCW flags values defined :
 
 CCW_FLAG_DC        - data chaining
 CCW_FLAG_CC        - command chaining
-CCW_FLAG_SLI       - suppress incorrct length
+CCW_FLAG_SLI       - suppress incorrect length
 CCW_FLAG_SKIP      - skip
 CCW_FLAG_PCI       - PCI
 CCW_FLAG_IDA       - indirect addressing
@@ -348,7 +348,7 @@ The ccw_device_start() function returns :
           not online.
 
 When the I/O request completes, the CDS first level interrupt handler will
-accumalate the status in a struct irb and then call the device interrupt handler.
+accumulate the status in a struct irb and then call the device interrupt handler.
 The intparm field will contain the value the device driver has associated with a 
 particular I/O request. If a pending device status was recognized, 
 intparm will be set to 0 (zero). This may happen during I/O initiation or delayed
@@ -433,7 +433,7 @@ puts the CPU into I/O disabled state by preserving the current PSW flags.
 
 The device driver is allowed to issue the next ccw_device_start() call from
 within its interrupt handler already. It is not required to schedule a
-bottom-half, unless an non deterministicly long running error recovery procedure
+bottom-half, unless an non deterministically long running error recovery procedure
 or similar needs to be scheduled. During I/O processing the Linux/390 generic
 I/O device driver support has already obtained the IRQ lock, i.e. the handler
 must not try to obtain it again when calling ccw_device_start() or we end in a
index 78a77624a7168ff141ac5e7a1ea9728907a089e6..29dee792c8875d00a09fe7ce5aa395e6dcf02186 100644 (file)
@@ -61,9 +61,9 @@ Example:      z990 crypto instruction for SHA1 algorithm is available
                -> when the sha1 algorithm is requested through the crypto API
                (which has a module autoloader) the z990 module will be loaded.
 
-TBD:   a userspace module probin mechanism
+TBD:   a userspace module probing mechanism
        something like 'probe sha1 sha1_z990 sha1' in modprobe.conf
-       -> try module sha1_z990, if it fails to load load standard module sha1
+       -> try module sha1_z990, if it fails to load standard module sha1
        the 'probe' statement is currently not supported in modprobe.conf
 
 
index efb674eda4d46da2b3490ebd51b001c712066171..62c082387aea294ca627f9e0f9cd6514fb4c6983 100644 (file)
@@ -157,7 +157,7 @@ notify: This function is called by the common I/O layer for some state changes
        * In online state, device detached (CIO_GONE) or last path gone
          (CIO_NO_PATH). The driver must return !0 to keep the device; for
          return code 0, the device will be deleted as usual (also when no
-         notify function is registerd). If the driver wants to keep the
+         notify function is registered). If the driver wants to keep the
          device, it is moved into disconnected state.
        * In disconnected state, device operational again (CIO_OPER). The
          common I/O layer performs some sanity checks on device number and
@@ -262,7 +262,7 @@ attribute 'online' which can be 0 or 1.
 -----------
 
 The netiucv driver creates an attribute 'connection' under
-bus/iucv/drivers/netiucv. Piping to this attibute creates a new netiucv
+bus/iucv/drivers/netiucv. Piping to this attribute creates a new netiucv
 connection to the specified host.
 
 Netiucv connections show up under devices/iucv/ as "netiucv<ifnum>". The interface
index d843bb04906edd079cf5fc729db5179230087444..beeaa4b244276f40dfdd03b7d50594ca27addf58 100644 (file)
@@ -83,7 +83,7 @@ This loads the module and sets the DCSS name to "MYDCSS".
 
 NOTE:
 -----
-This API provides no interface to control the *MONITOR service, e.g. specifiy
+This API provides no interface to control the *MONITOR service, e.g. specify
 which data should be collected. This can be done by the CP command MONITOR
 (Class E privileged), see "CP Command and Utility Reference".
 
index e321a8ed2a2d6bf78581673b967cc9fe45186435..000230cd26dbe49659b5d8001ba7fda3ffb1cbad 100644 (file)
@@ -11,7 +11,7 @@ where log records can be stored efficiently in memory, where each component
 (e.g. device drivers) can have one separate debug log.
 One purpose of this is to inspect the debug logs after a production system crash
 in order to analyze the reason for the crash.
-If the system still runs but only a subcomponent which uses dbf failes,
+If the system still runs but only a subcomponent which uses dbf fails,
 it is possible to look at the debug logs on a live system via the Linux
 debugfs filesystem.
 The debug feature may also very useful for kernel and driver development.
@@ -65,7 +65,7 @@ Predefined views for hex/ascii, sprintf and raw binary data are provided.
 It is also possible to define other views. The content of
 a view can be inspected simply by reading the corresponding debugfs file.
 
-All debug logs have an an actual debug level (range from 0 to 6).
+All debug logs have an actual debug level (range from 0 to 6).
 The default level is 3. Event and Exception functions have a 'level'
 parameter. Only debug entries with a level that is lower or equal
 than the actual level are written to the log. This means, when
@@ -83,8 +83,8 @@ Example:
 It is also possible to deactivate the debug feature globally for every
 debug log. You can change the behavior using  2 sysctl parameters in
 /proc/sys/s390dbf:
-There are currently 2 possible triggers, which stop the  debug feature
-globally. The first possbility is to use the "debug_active" sysctl. If
+There are currently 2 possible triggers, which stop the debug feature
+globally. The first possibility is to use the "debug_active" sysctl. If
 set to 1 the debug feature is running. If "debug_active" is set to 0 the
 debug feature is turned off.
 The second trigger which stops the debug feature is an kernel oops.
@@ -468,7 +468,7 @@ The hex_ascii view shows the data field in hex and ascii representation
 The raw view returns a bytestream as the debug areas are stored in memory.
 
 The sprintf view formats the debug entries in the same way as the sprintf
-function would do. The sprintf event/expection functions write to the
+function would do. The sprintf event/exception functions write to the
 debug entry a pointer to the format string (size = sizeof(long)) 
 and for each vararg a long value. So e.g. for a debug entry with a format 
 string plus two varargs one would need to allocate a (3 * sizeof(long)) 
@@ -556,7 +556,7 @@ The input_proc can be used to implement functionality when it is written to
 the view (e.g. like with 'echo "0" > /sys/kernel/debug/s390dbf/dasd/level).
 
 For header_proc there can be used the default function
-debug_dflt_header_fn() which is defined in in debug.h.
+debug_dflt_header_fn() which is defined in debug.h.
 and which produces the same header output as the predefined views.
 E.g:
 00 00964419409:440761 2 - 00 88023ec
index 2b75ef67c9fe7f6819c0ab49bd01dcff59a17b5f..cbd8db752acff8f9952305a12d5bdea883bec6a7 100644 (file)
@@ -15,7 +15,7 @@ Main Scheduling Methods
 void load_balance(runqueue_t *this_rq, int idle)
        Attempts to pull tasks from one cpu to another to balance cpu usage,
        if needed.  This method is called explicitly if the runqueues are
-       inbalanced or periodically by the timer tick.  Prior to calling,
+       imbalanced or periodically by the timer tick.  Prior to calling,
        the current runqueue must be locked and interrupts disabled.
 
 void schedule()
index 9d04e7bbf45fbd4e5ca93d75d87f4b2175a507e8..1605bf0cba8bd5da6b9f81502e7256094056d9bb 100644 (file)
@@ -93,9 +93,9 @@ and the goal is also to add a few new things:
 Design
 ======
 
-the core of the new scheduler are the following mechanizms:
+The core of the new scheduler contains the following mechanisms:
 
- - *two*, priority-ordered 'priority arrays' per CPU. There is an 'active'
+ - *two* priority-ordered 'priority arrays' per CPU. There is an 'active'
    array and an 'expired' array. The active array contains all tasks that
    are affine to this CPU and have timeslices left. The expired array
    contains all tasks which have used up their timeslices - but this array
index dc88ee2ab73d25127190ad54f185af92edb00152..6faad7e6417c89e82e761928393c9907410c5e0f 100644 (file)
@@ -1214,7 +1214,7 @@ Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
 
        * sr.c(sr_open): Do not allow opens with write access.
 
-Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
+Mon Jul 18 09:51:22 1994  Eric Youngdale  (eric@esp22)
 
        * Linux 1.1.31 released.
 
index 041780f428acefa250e82a58d292f4567513df70..3229b64cf24e46c30d3b11bc9a6a3db33cd247d6 100644 (file)
@@ -24,7 +24,7 @@ SCSI device:  I-O data CDPS-PX24 (CD-ROM drive)
     You can also use "cardctl" program (this program is in pcmcia-cs source
     code) to get more info.
 
-# cat /var/log/messgaes
+# cat /var/log/messages
 ...
 Jan  2 03:45:06 lindberg cardmgr[78]: unsupported card in socket 1
 Jan  2 03:45:06 lindberg cardmgr[78]:   product info: "WBT", "NinjaSCSI-3", "R1.0"
@@ -36,18 +36,18 @@ Socket 1:
   product info: "IO DATA", "CBSC16       ", "1"
 
 
-[2] Get Linux kernel source, and extract it to /usr/src.
-    Because NinjaSCSI driver requiers some SCSI header files in Linux kernel
-    source.
-    I recomend rebuilding your kernel. This eliminate some versioning problem.
+[2] Get the Linux kernel source, and extract it to /usr/src.
+    Because the NinjaSCSI driver requires some SCSI header files in Linux 
+    kernel source, I recommend rebuilding your kernel; this eliminates 
+    some versioning problems.
 $ cd /usr/src
 $ tar -zxvf linux-x.x.x.tar.gz
 $ cd linux
 $ make config
 ...
 
-[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
-    and make & install. This driver requies pcmcia-cs header file.
+[3] If you use this driver with Kernel 2.2, unpack pcmcia-cs in some directory
+    and make & install. This driver requires the pcmcia-cs header file.
 $ cd /usr/src
 $ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
 ...
@@ -59,10 +59,10 @@ $ emacs Makefile
 ...
 $ make
 
-[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+[5] Copy nsp_cs.ko to suitable place, like /lib/modules/<Kernel version>/pcmcia/ .
 
 [6] Add these lines to /etc/pcmcia/config .
-    If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
+    If you use pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
     So, you don't need to edit file. Just copy to /etc/pcmcia/ .
 
 -------------------------------------
index ee03678c80292c76f185bea3e589ccb65f1453a4..3367130e64f6508b5501cfc2d9170970a870c30c 100644 (file)
@@ -4,7 +4,7 @@ Introduction
 -------------------------
 The aacraid driver adds support for Adaptec (http://www.adaptec.com)
 RAID controllers. This is a major rewrite from the original
-Adaptec supplied driver. It has signficantly cleaned up both the code
+Adaptec supplied driver. It has significantly cleaned up both the code
 and the running binary size (the module is less than half the size of
 the original).
 
index 382b439b439e1ea8c16ee2326e1ab8469884455b..904d49e90ef267545b00546c1960919cfbe6d2fa 100644 (file)
@@ -81,7 +81,7 @@ The following information is available in this file:
           an SDTR with an offset of 0 to be sure the target
           knows we are async.  This works around a firmware defect
           in the Quantum Atlas 10K.
-        - Implement controller susupend and resume.
+        - Implement controller suspend and resume.
         - Clear PCI error state during driver attach so that we
           don't disable memory mapped I/O due to a stray write
           by some other driver probe that occurred before we
@@ -94,7 +94,7 @@ The following information is available in this file:
         - Add support for scsi_report_device_reset() found in
           2.5.X kernels.
         - Add 7901B support.
-        - Simplify handling of the packtized lun Rev A workaround.
+        - Simplify handling of the packetized lun Rev A workaround.
         - Correct and simplify handling of the ignore wide residue
           message.  The previous code would fail to report a residual
           if the transaction data length was even and we received
index 3481fcded4c2b5760bb40b79bde4602e369f2115..9b894f116d95b364d3c8cc862eaf1d7eb97d1b4e 100644 (file)
@@ -160,7 +160,7 @@ The following information is available in this file:
 
    6.2.34 (May 5th, 2003)
         - Fix locking regression instroduced in 6.2.29 that
-          could cuase a lock order reversal between the io_request_lock
+          could cause a lock order reversal between the io_request_lock
           and our per-softc lock.  This was only possible on RH9,
           SuSE, and kernel.org 2.4.X kernels.
 
index 79e5ac6cb6ff7c3a32d42f0f9c60586199b792f1..c92f4473193b06dbfd038e21a18ca4ccdaa2a213 100644 (file)
@@ -102,7 +102,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
     The hardware RAID devices sold by Adaptec are *NOT* supported by this
     driver (and will people please stop emailing me about them, they are
     a totally separate beast from the bare SCSI controllers and this driver
-    can not be retrofitted in any sane manner to support the hardware RAID
+    cannot be retrofitted in any sane manner to support the hardware RAID
     features on those cards - Doug Ledford).
     
 
@@ -241,7 +241,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
         that instead of dumping the register contents on the card, this
        option dumps the contents of the sequencer program RAM.  This gives
        the ability to verify that the instructions downloaded to the
-       card's sequencer are indeed what they are suppossed to be.  Again,
+       card's sequencer are indeed what they are supposed to be.  Again,
        unless you have documentation to tell you how to interpret these
        numbers, then it is totally useless.
        
@@ -317,7 +317,7 @@ linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD
        initial DEVCONFIG values for each of your aic7xxx controllers as
        they are listed, and also record what the machine is detecting as
        the proper termination on your controllers.  NOTE: the order in
-       which the initial DEVCONFIG values are printed out is not gauranteed
+       which the initial DEVCONFIG values are printed out is not guaranteed
        to be the same order as the SCSI controllers are registered.  The
        above option and this option both work on the order of the SCSI
        controllers as they are registered, so make sure you match the right
index ae3b79a2d275f3815555ee35631dcb7b4a4fb62d..88219f96633d141ba9ccc63b28ba2746ec4f6f9e 100644 (file)
@@ -20,7 +20,7 @@ Parameters
 ----------
 The driver uses the settings from the EEPROM set in the SCSI BIOS 
 setup. If there is no EEPROM, the driver uses default values.
-Both can be overriden by command line parameters (module or kernel
+Both can be overridden by command line parameters (module or kernel
 parameters).
 
 The following parameters are available:
index 6e45e70243e56b35681cc0ed4d3380e00d9b7a88..f36dc0e7c8dafb4d1c4b9617fd772b86cedda0f6 100644 (file)
@@ -48,7 +48,7 @@
  *      Implemented suggestions from Alan Cox
  *      Added calculation of resid for sg layer
  *      Better error handling
- *         Added checking underflow condtions 
+ *         Added checking underflow conditions 
  *         Added DATAPROTECT checking
  *         Changed error return codes
  *         Fixed pointer bug in bus reset routine
index d16ce5b540f469cdcc5ebc9681e4e608967e1590..35f6b8ed229587eb5a9733fe48594b9123b5e32e 100644 (file)
 
    In a second step of the driver development, the following improvement has
    been applied: The first approach limited the number of devices to 7, far
-   fewer than the 15 that it could usem then it just maped ldn -> 
+   fewer than the 15 that it could use, then it just mapped ldn -> 
    (ldn/8,ldn%8) for pun,lun.  We ended up with a real mishmash of puns
    and luns, but it all seemed to work.
 
    device to be existant, but it has no ldn assigned, it gets a ldn out of 7 
    to 14. The numbers are assigned in cyclic order. Therefore it takes 8 
    dynamical reassignments on the SCSI-devices, until a certain device 
-   loses its ldn again. This assures, that dynamical remapping is avoided 
+   loses its ldn again. This assures that dynamical remapping is avoided 
    during intense I/O between up to 15 SCSI-devices (means pun,lun 
-   combinations). A further advantage of this method is, that people who
+   combinations). A further advantage of this method is that people who
    build their kernel without probing on all luns will get what they expect,
    because the driver just won't assign everything with lun>0 when 
-   multpile lun probing is inactive.
+   multiple lun probing is inactive.
  
    2.4 SCSI-Device Order
    ---------------------
    2.6 Abort & Reset Commands
    --------------------------
    These are implemented with busy waiting for interrupt to arrive.
-   ibmmca_reset() and ibmmca_abort() do not work sufficently well
-   up to now and need still a lot of development work. But, this seems
-   to be even a problem with other SCSI-low level drivers, too. However,
+   ibmmca_reset() and ibmmca_abort() do not work sufficiently well
+   up to now and need still a lot of development work. This seems
+   to be a problem with other low-level SCSI drivers too, however
    this should be no excuse.
 
    2.7 Disk Geometry
       not like sending commands to non-existing SCSI-devices and will react
       with a command error as a sign of protest. While this error is not
       present on IBM SCSI Adapter w/cache, it appears on IBM Integrated SCSI
-      Adapters. Therefore, I implemented a workarround to forgive those 
-      adapters their protests, but it is marked up in the statisctis, so
+      Adapters. Therefore, I implemented a workaround to forgive those 
+      adapters their protests, but it is marked up in the statistics, so
       after a successful boot, you can see in /proc/scsi/ibmmca/<host_number>
       how often the command errors have been forgiven to the SCSI-subsystem.
       If the number is bigger than 0, you have a SCSI subsystem of older
         not accept this, as they stick quite near to ANSI-SCSI and report
         a COMMAND_ERROR message which causes the driver to panic. The main
         problem was located around the INQUIRY command. Now, for all the
-        mentioned commands, the buffersize, sent to the adapter is at 
+        mentioned commands, the buffersize sent to the adapter is at 
         maximum 255 which seems to be a quite reasonable solution. 
-        TEST_UNIT_READY gets a buffersize of 0 to make sure, that no 
+        TEST_UNIT_READY gets a buffersize of 0 to make sure that no 
         data is transferred in order to avoid any possible command failure.
-      2) On unsuccessful TEST_UNIT_READY, the midlevel-driver has to send
-         a REQUEST_SENSE in order to see, where the problem is located. This
+      2) On unsuccessful TEST_UNIT_READY, the mid-level driver has to send
+         a REQUEST_SENSE in order to see where the problem is located. This
         REQUEST_SENSE may have various length in its answer-buffer. IBM
-        SCSI-subsystems report a command failure, if the returned buffersize
-        is different from the sent buffersize, but this can be supressed by
+        SCSI-subsystems report a command failure if the returned buffersize
+        is different from the sent buffersize, but this can be suppressed by
         a special bit, which is now done and problems seem to be solved.
    2) Code adaption to all kernel-releases. Now, the 3.2 code compiles on 
       2.0.x, 2.1.x, 2.2.x and 2.3.x kernel releases without any code-changes.
    
      Q: "Reset SCSI-devices at boottime" halts the system at boottime, why?
      A: This is only tested with the IBM SCSI Adapter w/cache. It is not
-        yet prooved to run on other adapters, however you may be lucky.
+        yet proven to run on other adapters, however you may be lucky.
        In version 3.1d this has been hugely improved and should work better,
        now. Normally you really won't need to activate this flag in the
        kernel configuration, as all post 1989 SCSI-devices should accept
        The parameter 'normal' sets the new industry standard, starting
        from pun 0, scanning up to pun 6. This allows you to change your 
        opinion still after having already compiled the kernel.
-     Q: Why I cannot find the IBM MCA SCSI support in the config menue?
+     Q: Why can't I find IBM MCA SCSI support in the config menu?
      A: You have to activate MCA bus support, first.
      Q: Where can I find the latest info about this driver?
      A: See the file MAINTAINERS for the current WWW-address, which offers
         Guide) what has to be done for reset, we still share the bad shape of
        the reset functions with all other low level SCSI-drivers. 
        Astonishingly, reset works in most cases quite ok, but the harddisks
-       won't run in synchonous mode anymore after a reset, until you reboot.
+       won't run in synchronous mode anymore after a reset, until you reboot.
      Q: Why does my XXX w/Cache adapter not use read-prefetch?
      A: Ok, that is not completely possible. If a cache is present, the 
         adapter tries to use it internally. Explicitly, one can use the cache
index ff864c0f494c611d6a1b737c441730fa1bddddad..3c7cea51e6873ce979b87b891a9b92ad5c729235 100644 (file)
@@ -4,11 +4,11 @@
 Overview:
 --------
 
-Different classes of controllers from LSI Logic, accept and respond to the
+Different classes of controllers from LSI Logic accept and respond to the
 user applications in a similar way. They understand the same firmware control
 commands. Furthermore, the applications also can treat different classes of
 the controllers uniformly. Hence it is logical to have a single module that
-interefaces with the applications on one side and all the low level drivers
+interfaces with the applications on one side and all the low level drivers
 on the other.
 
 The advantages, though obvious, are listed for completeness:
index 822d2aca3700ca57c0dca6ede0ad53bac139b6b5..58ad8db333d9f6b5aeb2f011b0f9f0ee64bf70c0 100644 (file)
@@ -70,7 +70,7 @@ Written by Gerard Roudier <groudier@free.fr>
 15. SCSI problem troubleshooting
       15.1 Problem tracking
       15.2 Understanding hardware error reports
-16. Synchonous transfer negotiation tables
+16. Synchronous transfer negotiation tables
       16.1 Synchronous timings for 53C875 and 53C860 Ultra-SCSI controllers
       16.2 Synchronous timings for fast SCSI-2 53C8XX controllers
 17. Serial NVRAM support (by Richard Waltham)
@@ -96,10 +96,10 @@ The original driver has been written for 386bsd and FreeBSD by:
 It is now available as a bundle of 2 drivers:
 
 - ncr53c8xx generic driver that supports all the SYM53C8XX family including 
-  the ealiest 810 rev. 1, the latest 896 (2 channel LVD SCSI controller) and
+  the earliest 810 rev. 1, the latest 896 (2 channel LVD SCSI controller) and
   the new 895A (1 channel LVD SCSI controller).
 - sym53c8xx enhanced driver (a.k.a. 896 drivers) that drops support of oldest 
-  chips in order to gain advantage of new features, as LOAD/STORE intructions 
+  chips in order to gain advantage of new features, as LOAD/STORE instructions 
   available since the 810A and hardware phase mismatch available with the 
   896 and the 895A.
 
@@ -207,7 +207,7 @@ The 896 and the 895A allows handling of the phase mismatch context from
 SCRIPTS (avoids the phase mismatch interrupt that stops the SCSI processor 
 until the C code has saved the context of the transfer).
 Implementing this without using LOAD/STORE instructions would be painfull 
-and I did'nt even want to try it.
+and I didn't even want to try it.
 
 The 896 chip supports 64 bit PCI transactions and addressing, while the 
 895A supports 32 bit PCI transactions and 64 bit addressing.
@@ -631,8 +631,8 @@ string variable using 'insmod'.
 
 A boot setup command for the ncr53c8xx (sym53c8xx) driver begins with the 
 driver name "ncr53c8xx="(sym53c8xx). The kernel syntax parser then expects 
-an optionnal list of integers separated with comma followed by an optional 
-list of  comma-separated strings. Example of boot setup command under lilo 
+an optional list of integers separated with comma followed by an optional 
+list of comma-separated strings. Example of boot setup command under lilo 
 prompt:
 
 lilo: linux root=/dev/hda2 ncr53c8xx=tags:4,sync:10,debug:0x200
@@ -778,7 +778,7 @@ port address 0x1400.
   Some scsi boards use a 875 (ultra wide) and only supply narrow connectors.
   If you have connected a wide device with a 50 pins to 68 pins cable 
   converter, any accepted wide negotiation will break further data transfers.
-  In such a case, using "wide:0" in the bootup command will be helpfull
+  In such a case, using "wide:0" in the bootup command will be helpful. 
 
 10.2.14 Differential mode
         diff:0 never set up diff mode
@@ -899,7 +899,7 @@ boot setup can be:
     ncr53c8xx=safe:y,mpar:y
     ncr53c8xx=safe:y
 
-My personnal system works flawlessly with the following equivalent setup:
+My personal system works flawlessly with the following equivalent setup:
 
    ncr53c8xx=mpar:y,spar:y,disc:y,specf:1,fsn:n,ultra:2,fsn:n,revprob:n,verb:1\
              tags:32,sync:12,debug:0,burst:7,led:1,wide:1,settle:2,diff:0,irqm:0
@@ -1151,7 +1151,7 @@ Driver files:
 
 New driver versions are made available separately in order to allow testing 
 changes and new features prior to including them into the linux kernel 
-distribution. The following URL provides informations on latest avalaible 
+distribution. The following URL provides information on latest available 
 patches: 
 
       ftp://ftp.tux.org/pub/people/gerard-roudier/README
@@ -1382,7 +1382,7 @@ SCSI standards, chip cores functionnals and internal driver data structures.
 You are not required to decode and understand them, unless you want to help 
 maintain the driver code.
 
-16. Synchonous transfer negotiation tables
+16. Synchronous transfer negotiation tables
 
 Tables below have been created by calling the routine the driver uses
 for synchronisation negotiation timing calculation and chip setting.
index ce574e7791abb9ab8c55cd2d14e8893ebec5954a..f536907e241d101bcf6ac1f229288c482aaa9ba9 100644 (file)
@@ -56,8 +56,7 @@ Compile your kernel and install the modules.
 
 Now, your osst driver is inside the kernel or available as a module,
 depending on your choice during kernel config. You may still need to create
-the device nodes by calling the Makedevs.sh script (see below) manually,
-unless you use a devfs kernel, where this won't be needed.
+the device nodes by calling the Makedevs.sh script (see below) manually.
 
 To load your module, you may use the command 
 modprobe osst
index 5d9223bc1bd516c9035df9ab56968345b970dd9f..067ac394e0b27285b97feeda16859d9fc214b3f1 100644 (file)
@@ -3,7 +3,7 @@
 General Iomega ZIP drive page for Linux:
 http://www.torque.net/~campbell/
 
-Driver achive for old drivers:
+Driver archive for old drivers:
 http://www.torque.net/~campbell/ppa/
 
 Linux Parport page (parallel port)
index c132687b017a64ad77f5f8f2709705f32d36af05..d74bbd29eb3a3f2cc576e1fdc979ce2b8f99ccc9 100644 (file)
@@ -31,7 +31,7 @@ changers. But it allows to handle nearly all possible cases. It knows
   media transport - this one shuffles around the media, i.e. the
                     transport arm.  Also known as "picker".
   storage         - a slot which can hold a media.
-  import/export   - the same as above, but is accessable from outside,
+  import/export   - the same as above, but is accessible from outside,
                     i.e. there the operator (you !) can use this to
                     fill in and remove media from the changer.
                    Sometimes named "mailslot".
index ce767b90bb0dd288118fbee62df7176fcc9260fd..b964eef2f62fb5236caa6bd3b0cb33d19c645ccc 100644 (file)
@@ -160,7 +160,7 @@ ways.
  - Fine-grained EH callbacks
        LLDD can implement fine-grained EH callbacks and let SCSI
        midlayer drive error handling and call appropriate callbacks.
-       This will be dicussed further in [2-1].
+       This will be discussed further in [2-1].
 
  - eh_strategy_handler() callback
        This is one big callback which should perform whole error
@@ -194,7 +194,7 @@ lower layers and lower layers are ready to process or fail the scmd
 again.
 
  To achieve these goals, EH performs recovery actions with increasing
-severity.  Some actions are performed by issueing SCSI commands and
+severity.  Some actions are performed by issuing SCSI commands and
 others are performed by invoking one of the following fine-grained
 hostt EH callbacks.  Callbacks may be omitted and omitted ones are
 considered to fail always.
index 20e30cf31877ff71251a925162c08959c29a063e..5ff65b184265f9919ea8f1404a6c6ba63f617034 100644 (file)
@@ -249,7 +249,7 @@ BOOT TIME CONFIGURATION
 
 If the driver is compiled into the kernel, the same parameters can be
 also set using, e.g., the LILO command line. The preferred syntax is
-is to use the same keyword used when loading as module but prepended
+to use the same keyword used when loading as module but prepended
 with 'st.'. For instance, to set the maximum number of scatter/gather
 segments, the parameter 'st.max_sg_segs=xx' should be used (xx is the
 number of scatter/gather segments).
@@ -369,7 +369,7 @@ MTSETDRVBUFFER
                the device dependent address. It is recommended to set
                this flag unless there are tapes using the device
                dependent (from the old times) (global)
-            MT_ST_SYSV sets the SYSV sematics (mode)
+            MT_ST_SYSV sets the SYSV semantics (mode)
             MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
                the command to finish) for some commands (e.g., rewind)
             MT_ST_DEBUGGING debugging (global; debugging must be
index 7f516cdcd2628d871d130d267e9a7bb6edf60be9..26c8a08ca3eaf378fffc65805857df02e8d66003 100644 (file)
@@ -67,7 +67,7 @@ under Linux is contained in 2 files named sym_glue.h and sym_glue.c.
 Other drivers files are intended not to depend on the Operating System 
 on which the driver is used.
 
-The history of this driver can be summerized as follows:
+The history of this driver can be summarized as follows:
 
 1993: ncr driver written for 386bsd and FreeBSD by:
           Wolfgang Stanglmeier        <wolf@cologne.de>
@@ -684,7 +684,7 @@ Field H : SCNTL3 Scsi Control Register 3
           Contains the setting of timing values for both asynchronous and 
           synchronous data transfers. 
 Field I : SCNTL4 Scsi Control Register 4
-          Only meaninful for 53C1010 Ultra3 controllers.
+          Only meaningful for 53C1010 Ultra3 controllers.
 
 Understanding Fields J, K, L and dumps requires to have good knowledge of 
 SCSI standards, chip cores functionnals and internal driver data structures.
index df7a02bfb5bf66366289707c75d3a6cb2f0ebd57..8b2168aa4fc7e25d318b9127d1f58d43629665ad 100644 (file)
@@ -27,7 +27,7 @@ Tekram DC390(T) adapter. This is where the name comes from: tm = Tekram
 scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F
 (NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter,
 tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more,
-as the ncr53c8xx is perfectly supporting these adpaters since some time.
+as the ncr53c8xx is perfectly supporting these adapters since some time.
 
 The driver first appeared in April 1996, exclusively supported the DC390 
 and has been enhanced since then in various steps. In May 1998 support for 
@@ -381,7 +381,7 @@ Please see http://www.garloff.de/kurt/linux/dc390/problems.html
   replaced by the dev index of your scanner). You may try to reset your SCSI
   bus afterwards (echo "RESET" >/proc/scsi/tmscsim/?).
   The problem seems to be solved as of 2.0d18, thanks to Andreas Rick.
-* If there is a valid partition table, the driver will use it for determing
+* If there is a valid partition table, the driver will use it for determining
   the mapping. If there's none, a reasonable mapping (Symbios-like) will be
   assumed. Other operating systems may not like this mapping, though
   it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the
index 5b04f7f306fc49a8c222a53c615d8f0cf8f7d907..05b4ba89d28ca27f4cde52797475d9f8e13caf7e 100644 (file)
@@ -69,7 +69,7 @@ might specify the halt option:
 
   kgdb=halt
 
-Boot the TARGET machinem, which will appear to hang. 
+Boot the TARGET machine, which will appear to hang. 
 
 On your DEVELOPMENT machine, cd to the source directory and run the gdb
 program.  (This is likely to be a cross GDB which runs on your host but
index e6b57dd46a4f37ba4eb7c41da93b344e7aaa8289..138673a907f581e58fbeb07fa9b1a73497ca4177 100644 (file)
@@ -57,11 +57,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                - Default: 1
                - For auto-loading more than one card, specify this
                  option together with snd-card-X aliases.
-    device_mode
-               - permission mask for dynamic sound device filesystem
-               - This is available only when DEVFS is enabled
-               - Default: 0666
-               - E.g.: device_mode=0660
 
   
   Module snd-pcm-oss
@@ -1268,8 +1263,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
     Note: on some notebooks the buffer address cannot be detected
     automatically, or causes hang-up during initialization.
-    In such a case, specify the buffer top address explicity via
-    buffer_top option.
+    In such a case, specify the buffer top address explicitly via
+    the buffer_top option.
     For example,
       Sony F250: buffer_top=0x25a800
       Sony F270: buffer_top=0x272800
@@ -1887,7 +1882,7 @@ options snd-ens1371 index=1
 # OSS/Free portion
 alias sound-slot-0 snd-interwave
 alias sound-slot-1 snd-ens1371
------ /etc/moprobe.conf
+----- /etc/modprobe.conf
 
 In this example, the interwave card is always loaded as the first card
 (index 0) and ens1371 as the second (index 1).
@@ -1915,21 +1910,6 @@ Please note that the device mapping above may be varied via the module
 options of snd-pcm-oss module.
 
 
-DEVFS support
-=============
-
-The ALSA driver fully supports the devfs extension.
-You should add lines below to your devfsd.conf file:
-
-LOOKUP snd MODLOAD ACTION snd
-REGISTER ^sound/.* PERMISSIONS root.audio 660
-REGISTER ^snd/.* PERMISSIONS root.audio 660
-
-Warning: These lines assume that you have the audio group in your system.
-         Otherwise replace audio word with another group name (root for
-         example).
-
-
 Proc interfaces (/proc/asound)
 ==============================
 
index b535c2a198f8db9dec40079c2a107b600447ce25..e40cce83327c4488c38e4541aa5ae5a5877b3f61 100644 (file)
@@ -126,7 +126,7 @@ Here is a list of supported device_setup values for this device:
    - Alsa driver default mode
    - maintains backward compatibility with setups that do not use this 
      parameter by not introducing any change
-   - results sometimes in corrupted sound as decribed earlier
+   - results sometimes in corrupted sound as described earlier
  * device_setup=0x01
    - 16bits 48kHz mode with Di disabled
    - Ai,Ao,Do can be used at the same time
index 1872e24442a47537d7b0497ab2ea17067dc64f16..4b2b1538705634797a5893c61ca7eda527f256a3 100644 (file)
@@ -16,11 +16,11 @@ As default, ALSA driver assigns the first PCM device (i.e. hw:0,0 for
 card#0) for front and 4/6ch playbacks, while the second PCM device
 (hw:0,1) is assigned to the second DAC for rear playback.
 
-There are slight difference between two DACs.
+There are slight differences between the two DACs:
 
 - The first DAC supports U8 and S16LE formats, while the second DAC
   supports only S16LE.
-- The seconde DAC supports only two channel stereo.
+- The second DAC supports only two channel stereo.
 
 Please note that the CM8x38 DAC doesn't support continuous playback
 rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000,
@@ -76,7 +76,7 @@ in alsa-lib.  For example, you can play a WAV file with 6 channels like
 
        % aplay -Dsurround51 sixchannels.wav
 
-For programmin the 4/6 channel playback, you need to specify the PCM
+For programming the 4/6 channel playback, you need to specify the PCM
 channels as you like and set the format S16LE.  For example, for playback
 with 4 channels,
 
index 4807ef79a94d8723168842a014e0250796cd98e7..077fbe25ebf44bca5cd9c16a819faebc60849121 100644 (file)
@@ -5486,7 +5486,7 @@ struct _snd_pcm_runtime {
   <chapter id="power-management">
     <title>Power Management</title>
     <para>
-      If the chip is supposed to work with with suspend/resume
+      If the chip is supposed to work with suspend/resume
       functions, you need to add the power-management codes to the
       driver. The additional codes for the power-management should be
       <function>ifdef</function>'ed with
index 5cb970612870e303ccec304272bdf83eb0f81a45..ef42c44fa1f238b7df24b9dbc06b56574c3dd4e1 100644 (file)
@@ -31,7 +31,7 @@ With a miXart8AES/EBU there is in addition 1 stereo digital input
 Formats
 -------
 U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE
-Sample rates : 8000 - 48000 Hz continously
+Sample rates : 8000 - 48000 Hz continuously
 
 Playback
 --------
@@ -39,7 +39,7 @@ For instance the playback devices are configured to have max. 4
 substreams performing hardware mixing. This could be changed to a
 maximum of 24 substreams if wished.
 Mono files will be played on the left and right channel. Each channel
-can be muted for each stream to use 8 analog/digital outputs seperately.
+can be muted for each stream to use 8 analog/digital outputs separately.
 
 Capture
 -------
@@ -97,4 +97,4 @@ COPYRIGHT
 =========
 
 Copyright (c) 2003 Digigram SA <alsa@digigram.com>
-Distributalbe under GPL.
+Distributable under GPL.
index 1fe48846d78fdcdc54c9f9c3a879d2795d3210f7..f738b296440a55a3a3cc86b0f0039bff1c2d2067 100644 (file)
@@ -71,7 +71,7 @@ The status of MIDI I/O is found in midi* files.  It shows the device
 name and the received/transmitted bytes through the MIDI device.
 
 When the card is equipped with AC97 codecs, there are codec97#*
-subdirectories (desribed later).
+subdirectories (described later).
 
 When the OSS mixer emulation is enabled (and the module is loaded),
 oss_mixer file appears here, too.  This shows the current mapping of
@@ -161,12 +161,12 @@ seq/drivers
        Lists the currently available ALSA sequencer drivers.
 
 seq/clients
-       Shows the list of currently available sequencer clinets and
+       Shows the list of currently available sequencer clients and
        ports.  The connection status and the running status are shown
        in this file, too.
 
 seq/queues
-       Lists the currently allocated/running sequener queues.
+       Lists the currently allocated/running sequencer queues.
 
 seq/timer
        Lists the currently allocated/running sequencer timers.
@@ -182,10 +182,10 @@ When the problem is related with PCM, first try to turn on xrun_debug
 mode.  This will give you the kernel messages when and where xrun
 happened.
 
-If it's really a bug, report it with the following information
+If it's really a bug, report it with the following information:
 
   - the name of the driver/card, show in /proc/asound/cards
-  - the reigster dump, if available (e.g. card*/cmipci)
+  - the register dump, if available (e.g. card*/cmipci)
 
 when it's a PCM problem,
 
diff --git a/Documentation/sound/oss/AWE32 b/Documentation/sound/oss/AWE32
deleted file mode 100644 (file)
index cb179bf..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-       Installing and using Creative AWE midi sound under Linux.
-
-This documentation is devoted to the Creative Sound Blaster AWE32, AWE64 and 
-SB32.
-
-1) Make sure you have an ORIGINAL Creative SB32, AWE32 or AWE64 card. This
-   is important, because the driver works only with real Creative cards.
-
-2) The first thing you need to do is re-compile your kernel with support for
-   your sound card. Run your favourite tool to configure the kernel and when
-   you get to the "Sound" menu you should enable support for the following:
-
-   Sound card support,
-   OSS sound modules,
-   100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support,
-   AWE32 synth
-
-   If your card is "Plug and Play" you will also need to enable these two
-   options, found under the "Plug and Play configuration" menu:
-
-   Plug and Play support
-   ISA Plug and Play support
-
-   Now compile and install the kernel in normal fashion. If you don't know
-   how to do this you can find instructions for this in the README file
-   located in the root directory of the kernel source.
-
-3) Before you can start playing midi files you will have to load a sound
-   bank file. The utility needed for doing this is called "sfxload", and it
-   is one of the utilities found in a package called "awesfx". If this
-   package is not available in your distribution you can download the AWE
-   snapshot from Creative Labs Open Source website:
-
-   http://www.opensource.creative.com/snapshot.html
-
-   Once you have unpacked the AWE snapshot you will see a "awesfx"
-   directory. Follow the instructions in awesfx/docs/INSTALL to install the
-   utilities in this package. After doing this, sfxload should be installed
-   as:
-
-   /usr/local/bin/sfxload
-
-   To enable AWE general midi synthesis you should also get the sound bank
-   file for general midi from:
-
-   http://members.xoom.com/yar/synthgm.sbk.gz
-
-   Copy it to a directory of your choice, and unpack it there.
-
-4) Edit /etc/modprobe.conf, and insert the following lines at the end of the
-   file:
-
-  alias sound-slot-0 sb
-  alias sound-service-0-1 awe_wave
-  install awe_wave /sbin/modprobe --first-time -i awe_wave && /usr/local/bin/sfxload PATH_TO_SOUND_BANK_FILE
-
-  You will of course have to change "PATH_TO_SOUND_BANK_FILE" to the full
-  path of of the sound bank file. That will enable the Sound Blaster and AWE
-  wave synthesis. To play midi files you should get one of these programs if
-  you don't already have them:
-
-  Playmidi:                    http://playmidi.openprojects.net
-
-  AWEMidi Player (drvmidi)     Included in the previously mentioned AWE
-                               snapshot.
-
-  You will probably have to pass the "-e" switch to playmidi to have it use
-  your midi device. drvmidi should work without switches.
-
-  If something goes wrong please e-mail me. All comments and suggestions are
-  welcome.
-
-                   Yaroslav Rosomakho (alons55@dialup.ptt.ru)
-                           http://www.yar.opennet.ru
-
-Last Updated: Feb 3 2001
diff --git a/Documentation/sound/oss/CMI8338 b/Documentation/sound/oss/CMI8338
deleted file mode 100644 (file)
index 387d058..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-Audio driver for CM8338/CM8738 chips by Chen-Li Tien
-
-
-HARDWARE SUPPORTED
-================================================================================
-C-Media CMI8338
-C-Media CMI8738
-On-board C-Media chips
-
-
-STEPS TO BUILD DRIVER
-================================================================================
-
-  1. Backup the Config.in and Makefile in the sound driver directory
-     (/usr/src/linux/driver/sound).
-     The Configure.help provide help when you config driver in step
-     4, please backup the original one (/usr/src/linux/Document) and
-     copy this file.
-     The cmpci is document for the driver in detail, please copy it
-     to /usr/src/linux/Document/sound so you can refer it. Backup if
-     there is already one.
-
-  2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above
-     directory.
-
-  3. Change directory to /usr/src/linux
-
-  4. Config cm8338 driver by 'make menuconfig', 'make config' or
-     'make xconfig' command.
-
-  5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI
-     driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
-     For driver option, please refer 'DRIVER PARAMETER'
-
-  6. Compile the kernel if necessary.
-
-  7. Compile the modules by 'make modules'.
-
-  8. Install the modules by 'make modules_install'
-
-
-INSTALL DRIVER
-================================================================================
-
-  1. Before first time to run the driver, create module dependency by
-     'depmod -a'
-
-  2. To install the driver manually, enter 'modprobe cmpci'.
-
-  3. Driver installation for various distributions:
-
-    a. Slackware 4.0
-       Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules
-       file.so you can start the driver automatically each time booting.
-
-    b. Caldera OpenLinux 2.2
-       Use LISA to load the cmpci module.
-
-    c. RedHat 6.0 and S.u.S.E. 6.1
-       Add following command in /etc/conf.modules:
-
-       alias sound cmpci
-
-       also visit http://www.cmedia.com.tw for installation instruction.
-
-DRIVER PARAMETER
-================================================================================
-
-  Some functions for the cm8738 can be configured in Kernel Configuration
-  or modules parameters. Set these parameters to 1 to enable.
-
-  mpuio:       I/O ports base for MPU-401, 0 if disabled.
-  fmio:                I/O ports base for OPL-3, 0 if disabled.
-  spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
-               CD-ROM or DVD-ROM.
-  spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
-                directly.
-  speakers:     Number of speakers used.
-  use_line_as_rear:Enable this if you want to use line-in as
-                rear-out.
-  use_line_as_bass:Enable this if you want to use line-in as
-                bass-out.
-  joystick:    Enable joystick. You will need to install Linux joystick
-               driver.
-
diff --git a/Documentation/sound/oss/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe
deleted file mode 100644 (file)
index 310f42c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-================================================================
-       INSTALLATION OF AWE32 SOUND DRIVER FOR LINUX
-       Takashi Iwai    <iwai@ww.uni-erlangen.de>
-================================================================
-
-----------------------------------------------------------------
-* Attention to SB-PnP Card Users
-
-If you're using PnP cards, the initialization of PnP is required
-before loading this driver.  You have now three options:
-  1. Use isapnptools.
-  2. Use in-kernel isapnp support.
-  3. Initialize PnP on DOS/Windows, then boot linux by loadlin.
-In this document, only the case 1 case is treated.
-
-----------------------------------------------------------------
-* Installation on Red Hat 5.0 Sound Driver
-
-Please use install-rh.sh under RedHat5.0 directory.
-DO NOT USE install.sh below.
-See INSTALL.RH for more details.
-
-----------------------------------------------------------------
-* Installation/Update by Shell Script
-
-  1. Become root
-
-       % su
-
-  2. If you have never configured the kernel tree yet, run make config
-    once (to make dependencies and symlinks).
-
-       # cd /usr/src/linux
-       # make xconfig
-    
-  3. Run install.sh script
-
-       # sh ./install.sh
-
-  4. Configure your kernel
-
-       (for Linux 2.[01].x user)
-       # cd /usr/src/linux
-       # make xconfig (or make menuconfig)
-
-       (for Linux 1.2.x user)
-       # cd /usr/src/linux
-       # make config
-
-    Answer YES to both "lowlevel drivers" and "AWE32 wave synth" items 
-    in Sound menu.  ("lowlevel drivers" will appear only in 2.x
-    kernel.)
-
-  5. Make your kernel (and modules), and install them as usual.
-
-       5a. make kernel image
-               # make zImage
-
-       5b. make modules and install them
-               # make modules && make modules_install
-
-       5c. If you're using lilo, copy the kernel image and run lilo.
-           Otherwise, copy the kernel image to suitable directory or
-           media for your system.
-
-  6. Reboot the kernel if necessary.
-       - If you updated only the modules, you don't have to reboot
-         the system.  Just remove the old sound modules here.
-               in 
-               # rmmod sound.o         (linux-2.0 or OSS/Free)
-               # rmmod awe_wave.o      (linux-2.1)
-
-  7. If your AWE card is a PnP and not initialized yet, you'll have to
-    do it by isapnp tools.  Otherwise, skip to 8.
-
-       This section described only a brief explanation.  For more
-       details, please see the AWE64-Mini-HOWTO or isapnp tools FAQ.
-
-       7a. If you have no isapnp.conf file, generate it by pnpdump.
-           Otherwise, skip to 7d.
-               # pnpdump > /etc/isapnp.conf
-
-       7b. Edit isapnp.conf file.  Comment out the appropriate
-           lines containing desirable I/O ports, DMA and IRQs.
-           Don't forget to enable (ACT Y) line.
-
-       7c. Add two i/o ports (0xA20 and 0xE20) in WaveTable part.
-           ex)
-               (CONFIGURE CTL0048/58128 (LD 2
-               #     ANSI string -->WaveTable<--
-                 (IO 0 (BASE 0x0620))
-                 (IO 1 (BASE 0x0A20))
-                 (IO 2 (BASE 0x0E20))
-                 (ACT Y)
-               ))
-
-       7d. Load the config file.
-           CAUTION: This will reset all PnP cards!
-
-               # isapnp /etc/isapnp.conf
-
-  8. Load the sound module (if you configured it as a module):
-
-       for 2.0 kernel or OSS/Free monolithic module:
-
-               # modprobe sound.o
-
-       for 2.1 kernel:
-
-               # modprobe sound
-               # insmod uart401
-               # insmod sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330
-               (These values depend on your settings.)
-               # insmod awe_wave
-               (Be sure to load awe_wave after sb!)
-
-               See Documentation/sound/oss/AWE32 for
-               more details.
-
-  9. (only for obsolete systems) If you don't have /dev/sequencer
-     device file, make it according to Readme.linux file on
-     /usr/src/linux/drivers/sound. (Run a shell script included in
-     that file). <-- This file no longer exists in the recent kernels!
-
-  10. OK, load your own soundfont file, and enjoy MIDI!
-
-       % sfxload synthgm.sbk
-       % drvmidi foo.mid
-
-  11. For more advanced use (eg. dynamic loading, virtual bank and
-      etc.), please read the awedrv FAQ or the instructions in awesfx
-      and awemidi packages.
-
-Good luck!
diff --git a/Documentation/sound/oss/MAD16 b/Documentation/sound/oss/MAD16
deleted file mode 100644 (file)
index 865dbd8..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-(This recipe has been edited to update the configuration symbols,
- and change over to modprobe.conf for 2.6)
-
-From: Shaw Carruthers <shaw@shawc.demon.co.uk>
-
-I have been using mad16 sound for some time now with no problems, current
-kernel 2.1.89
-
-lsmod shows:
-
-mad16                   5176   0 
-sb                     22044   0  [mad16]
-uart401                 5576   0  [mad16 sb]
-ad1848                 14176   1  [mad16]
-sound                  61928   0  [mad16 sb uart401 ad1848]
-
-.config has:
-
-CONFIG_SOUND=m
-CONFIG_SOUND_ADLIB=m
-CONFIG_SOUND_MAD16=m
-CONFIG_SOUND_YM3812=m
-
-modprobe.conf has:
-
-alias char-major-14-* mad16
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1  && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-
-To get the built in mixer to work this needs to be:
-
-options adlib_card io=0x388     # FM synthesizer
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1 mpu_io=816 mpu_irq=5 && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-The addition of the "mpu_io=816 mpu_irq=5" to the mad16 options line is
-
-------------------------------------------------------------------------
-The mad16 module in addition supports the following options:
-
-option:                        meaning:                        default:
-joystick=0,1           disabled, enabled               disabled
-cdtype=0x00,0x02,0x04, disabled, Sony CDU31A,          disabled
-       0x06,0x08,0x0a   Mitsumi, Panasonic,
-                       Secondary IDE, Primary IDE 
-cdport=0x340,0x320,                                    0x340
-       0x330,0x360
-cdirq=0,3,5,7,9,10,11  disabled, IRQ3, ...             disabled
-cddma=0,5,6,7          disabled, DMA5, ...             DMA5 for Mitsumi or IDE
-cddma=0,1,2,3          disabled, DMA1, ...             DMA3 for Sony or Panasonic
-opl4=0,1               OPL3, OPL4                      OPL3    
-
-for more details see linux/drivers/sound/mad16.c
-
-Rui Sousa
diff --git a/Documentation/sound/oss/Maestro b/Documentation/sound/oss/Maestro
deleted file mode 100644 (file)
index 4a80eb3..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-       An OSS/Lite Driver for the ESS Maestro family of sound cards
-
-                       Zach Brown, December 1999
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-       http://www.zabbo.net/maestro/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-ESS Maestro Chip Family
------------------------
-
-There are 3 main variants of the ESS Maestro PCI sound chip.  The first
-is the Maestro 1.  It was originally produced by Platform Tech as the
-'AGOGO'.  It can be recognized by Platform Tech's PCI ID 0x1285 with
-0x0100 as the device ID.  It was put on some sound boards and a few laptops.  
-ESS bought the design and cleaned it up as the Maestro 2.  This starts
-their marking with the ESS vendor ID 0x125D and the 'year' device IDs.
-The Maestro 2 claims 0x1968 while the Maestro 2e has 0x1978.
-
-The various families of Maestro are mostly identical as far as this 
-driver is concerned.  It doesn't touch the DSP parts that differ (though
-it could for FM synthesis).
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves almost as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, and mmap()ing for playback behaves.  Capture/recording
-is limited due to oddities with the Maestro hardware.  One can only
-record in 16bit stereo.  For recording the maestro uses non interleaved
-stereo buffers so that mmap()ing the incoming data does not result in
-a ring buffer of LRLR data.  mmap()ing of the read buffers is therefore
-disallowed until this can be cleaned up.
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-
-The driver doesn't support MIDI or FM playback at the moment.  Typically
-the Maestro is wired to an MPU MIDI chip, but some hardware implementations
-don't.  We need to assemble a white list of hardware implementations that
-have MIDI wired properly before we can claim to support it safely.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound maestro'
-should also be added to your module configs (typically /etc/conf.modules)
-if you're using modular OSS/Lite sound and want to default to using a
-maestro chip.
-
-As this is a PCI device, the module does not need to be informed of
-any IO or IRQ resources it should use, it devines these from the
-system.  Sometimes, on sucky PCs, the BIOS fails to allocated resources
-for the maestro.  This will result in a message like:
-       maestro: PCI subsystem reports IRQ 0, this might not be correct.
-from the kernel.  Should this happen the sound chip most likely will
-not operate correctly.  To solve this one has to dig through their BIOS
-(typically entered by hitting a hot key at boot time) and figure out
-what magic needs to happen so that the BIOS will reward the maestro with
-an IRQ.  This operation is incredibly system specific, so you're on your
-own.  Sometimes the magic lies in 'PNP Capable Operating System' settings.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-The other, more interesting option, is 'dsps_order'.  Typically at
-install time the driver will only register one available /dev/dsp device
-for its use.  The 'dsps_order' module parameter allows for more devices
-to be allocated, as a power of two.  Up to 4 devices can be registered
-( dsps_order=2 ).  These devices act as fully distinct units and use
-separate channels in the maestro.
-
-Power Management
-----------------
-
-As of version 0.14, this driver has a minimal understanding of PCI
-Power Management.  If it finds a valid power management capability
-on the PCI device it will attempt to use the power management
-functions of the maestro.  It will only do this on Maestro 2Es and
-only on machines that are known to function well.  You can
-force the use of power management by setting the 'use_pm' module
-option to 1, or can disable it entirely by setting it to 0.
-
-When using power management, the driver does a few things
-differently.  It will keep the chip in a lower power mode
-when the module is inserted but /dev/dsp is not open.  This
-allows the mixer to function but turns off the clocks
-on other parts of the chip.  When /dev/dsp is opened the chip
-is brought into full power mode, and brought back down
-when it is closed.  It also powers down the chip entirely
-when the module is removed or the machine is shutdown.  This
-can have nonobvious consequences.  CD audio may not work
-after a power managing driver is removed.  Also, software that
-doesn't understand power management may not be able to talk
-to the powered down chip until the machine goes through a hard
-reboot to bring it back.
-
-.. more details ..
-------------------
-
-drivers/sound/maestro.c contains comments that hopefully explain
-the maestro implementation.
diff --git a/Documentation/sound/oss/Maestro3 b/Documentation/sound/oss/Maestro3
deleted file mode 100644 (file)
index a113718..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-       An OSS/Lite Driver for the ESS Maestro3 family of sound chips
-
-                       Zach Brown, January 2001
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-       http://www.zabbo.net/maestro3/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-Historically I've sucked pretty hard at actually doing that, however.
-
-ESS Maestro3 Chip Family
------------------------
-
-The 'Maestro3' is much like the Maestro2 chip.  The noted improvement
-is the removal of the silicon in the '2' that did PCM mixing.  All that
-work is now done through a custom DSP called the ASSP, the Asynchronus
-Specific Signal Processor.
-
-The 'Allegro' is a baby version of the Maestro3.  I'm not entirely clear
-on the extent of the differences, but the driver supports them both :)
-
-The 'Allegro' shows up as PCI ID 0x1988 and the Maestro3 as 0x1998,
-both under ESS's vendor ID of 0x125D.  The Maestro3 can also show up as
-0x199a when hardware strapping is used.
-
-The chip can also act as a multi function device.  The modem IDs follow
-the audio multimedia device IDs.  (so the modem part of an Allegro shows
-up as 0x1989)
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, with both read()/write(), and mmap().
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro3.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro3.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-The Allegro has an onchip AC'97.
-
-The driver doesn't support MIDI or FM playback at the moment.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO3 variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound-slot-0
-maestro3' should also be added to your module configs (typically
-/etc/modprobe.conf) if you're using modular OSS/Lite sound and want to
-default to using a maestro3 chip.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-One is 'external_amp', which tells the driver to attempt to enable
-an external amplifier.  This defaults to '1', you can tell the driver
-not to bother enabling such an amplifier by setting it to '0'.
-
-And the last is 'gpio_pin', which tells the driver which GPIO pin number
-the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
-If everything loads correctly and seems to be working but you get no sound, 
-try tweaking this value. 
-
-Systems known to need a different value
-        Panasonic ToughBook CF-72: gpio_pin=13 
-
-Power Management
-----------------
-
-This driver has a minimal understanding of PCI Power Management.  It will
-try and power down the chip when the system is suspended, and power
-it up with it is resumed.  It will also try and power down the chip
-when the machine is shut down.
diff --git a/Documentation/sound/oss/NEWS b/Documentation/sound/oss/NEWS
deleted file mode 100644 (file)
index a81e0ef..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-Linux 2.4 Sound Changes
-2000-September-25
-Christoph Hellwig, <hch@infradead.org>
-
-
-
-=== isapnp support
-
-The Linux 2.4 Kernel does have reliable in-kernel isapnp support.
-Some drivers (sb.o, ad1816.o awe_wave.o) do now support automatically
-detecting and configuring isapnp devices.
-If you have a not yet supported isapnp soundcard, mail me the content
-of '/proc/isapnp' on your system and some information about your card
-and its driver(s) so I can try to get isapnp working for it.
-
-
-
-=== soundcard resources on kernel commandline
-
-Before Linux 2.4 you had to specify the resources for sounddrivers
-statically linked into the kernel at compile time
-(in make config/menuconfig/xconfig). In Linux 2.4 the resources are
-now specified at the boot-time kernel commandline (e.g. the lilo
-'append=' line or everything that's after the kernel name in grub).
-Read the Configure.help entry for your card for the parameters.
-
-
-=== softoss is gone
-
-In Linux 2.4 the softoss in-kernel software synthesizer is no more aviable.
-Use a user space software synthesizer like timidity instead.
-
-
-
-=== /dev/sndstat and /proc/sound are gone
-
-In older Linux versions those files exported some information about the
-OSS/Free configuration to userspace. In Linux 2.3 they were removed because
-they did not support the growing number of pci soundcards and there were
-some general problems with this interface.
-
-
diff --git a/Documentation/sound/oss/OPL3-SA b/Documentation/sound/oss/OPL3-SA
deleted file mode 100644 (file)
index 66a9183..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-OPL3-SA1 sound driver (opl3sa.o)
-
----
-Note: This howto only describes how to setup the OPL3-SA1 chip; this info
-does not apply to the SA2, SA3, or SA4. 
----
-
-The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
-it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401
-and OPL3 FM Synth capabilities.
-
-You can enable inclusion of the driver via CONFIG_SOUND_OPL3SA1=m, or
-CONFIG_SOUND_OPL3SA1=y through 'make config/xconfig/menuconfig'.
-
-You'll need to know all of the relevant info (irq, dma, and io port) for the
-chip's WSS mode, since that is the mode the kernel sound driver uses, and of
-course you'll also need to know about where the MPU401 and OPL3 ports and
-IRQs are if you want to use those.
-
-Here's the skinny on how to load it as a module:
-
-       modprobe opl3sa io=0x530 irq=11 dma=0 dma2=1 mpu_io=0x330 mpu_irq=5
-
-Module options in detail:
-
-       io:     This is the WSS's port base.
-       irq:    This is the WSS's IRQ.
-       dma:    This is the WSS's DMA line. In my BIOS setup screen this was
-               listed as "WSS Play DMA"
-       dma2:   This is the WSS's secondary DMA line. My BIOS calls it the
-               "WSS capture DMA"
-       
-       mpu_io: This is the MPU401's port base.
-       mpu_irq: This is the MPU401's IRQ.
-
-If you'd like to use the OPL3 FM Synthesizer, make sure you enable
-CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module.
-
-Then a simple 'insmod opl3 io=0x388', and you now have FM Synth.
-
-You can also use the SoftOSS software synthesizer instead of the builtin OPL3.
-Here's how:
-
-Say 'y' or 'm' to "SoftOSS software wave table engine" in make config.
-
-If you said yes, the software synth is available once you boot your new
-kernel.
-
-If you chose to build it as a module, just insmod the resulting softoss2.o
-
-Questions? Comments?
-<stiker@northlink.com>
diff --git a/Documentation/sound/oss/README.awe b/Documentation/sound/oss/README.awe
deleted file mode 100644 (file)
index 80054cd..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-================================================================
-       AWE32 Sound Driver for Linux / FreeBSD
-               version 0.4.3; Nov. 1, 1998
-
-       Takashi Iwai <iwai@ww.uni-erlangen.de>
-================================================================
-
-* GENERAL NOTES
-
-This is a sound driver extension for SoundBlaster AWE32 and other
-compatible cards (AWE32-PnP, SB32, SB32-PnP, AWE64 & etc) to enable
-the wave synth operations.  The driver is provided for Linux 1.2.x
-and 2.[012].x kernels, as well as FreeBSD, on Intel x86 and DEC
-Alpha systems.
-
-This driver was written by Takashi Iwai <iwai@ww.uni-erlangen.de>,
-and provided "as is".  The original source (awedrv-0.4.3.tar.gz) and
-binary packages are available on the following URL:
-       http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/
-Note that since the author is apart from this web site, the update is
-not frequent now.
-
-
-* NOTE TO LINUX USERS
-
-To enable this driver on linux-2.[01].x kernels, you need turn on 
-"AWE32 synth" options in sound menu when configure your linux kernel
-and modules.  The precise installation procedure is described in the
-AWE64-Mini-HOWTO and linux-kernel/Documetation/sound/AWE32.
-
-If you're using PnP cards, the card must be initialized before loading
-the sound driver.  There're several options to do this:
-    - Initialize the card via ISA PnP tools, and load the sound module.
-    - Initialize the card on DOS, and load linux by loadlin.exe
-    - Use PnP kernel driver (for Linux-2.x.x)
-The detailed instruction for the solution using isapnp tools is found
-in many documents like above.  A brief instruction is also included in
-the installation document of this package.
-For PnP driver project, please refer to the following URL:
-       http://www-jcr.lmh.ox.ac.uk/~pnp/
-
-
-* USING THE DRIVER
-
-The awedrv has several different playing modes to realize easy channel 
-allocation for MIDI songs.  To hear the exact sound quality, you need
-to obtain the extended sequencer program, drvmidi or playmidi-2.5.
-
-For playing MIDI files, you *MUST* load the soundfont file on the
-driver previously by sfxload utility.  Otherwise you'll here no sounds 
-at all!  All the utilities and driver source packages are found in the
-above URL.  The sfxload program is included in the package
-awesfx-0.4.3.tgz.  Binary packages are available there, too.  See the
-instruction in each package for installation.
-
-Loading a soundfont file is very simple.  Just execute the command
-
-       % sfxload synthgm.sbk
-
-Then, sfxload transfers the file "synthgm.sbk" to the driver.
-Both SF1 and SF2 formats are accepted.
-
-Now you can hear midi musics by a midi player.
-
-       % drvmidi foo.mid
-
-If you run MIDI player after MOD player, you need to load soundfont
-files again, since MOD player programs clear the previous loaded
-samples by their own data.
-
-If you have only 512kb on the sound card, I recommend to use dynamic
-sample loading via -L option of drvmidi.  2MB GM/GS soundfont file is
-available in most midi files.
-
-       % sfxload synthgm
-       % drvmidi -L 2mbgmgs foo.mid
-
-This makes a big difference (believe me)!  For more details, please
-refer to the FAQ list which is available on the URL above.
-
-The current chorus, reverb and equalizer status can be changed by
-aweset utility program (included in awesfx package).  Note that
-some awedrv-native programs (like drvmidi and xmp) will change the
-current settings by themselves.  The aweset program is effective
-only for other programs like playmidi.
-
-Enjoy.
-
-
-* COMPILE FLAGS
-
-Compile conditions are defined in awe_config.h.
-
-[Compatibility Conditions]
-The following flags are defined automatically when using installation
-shell script.
-
-- AWE_MODULE_SUPPORT
-    indicates your Linux kernel supports module for each sound card
-    (in recent 2.1 or 2.2 kernels and unofficial patched 2.0 kernels
-    as distributed in the RH5.0 package).
-    This flag is automatically set when you're using 2.1.x kernels.
-    You can pass the base address and memory size via the following
-    module options,
-       io = base I/O port address (eg. 0x620)
-       memsize = DRAM size in kilobytes (eg. 512)
-    As default, AWE driver probes these values automatically.
-
-
-[Hardware Conditions]
-You DON'T have to define the following two values.
-Define them only when the driver couldn't detect the card properly.
-
-- AWE_DEFAULT_BASE_ADDR                (default: not defined)
-    specifies the base port address of your AWE32 card.
-    0 means to autodetect the address.
-
-- AWE_DEFAULT_MEM_SIZE         (default: not defined)
-    specifies the memory size of your AWE32 card in kilobytes.
-    -1 means to autodetect its size.
-    
-
-[Sample Table Size]
-From ver.0.4.0, sample tables are allocated dynamically (except
-Linux-1.2.x system), so you need NOT to touch these parameters.
-Linux-1.2.x users may need to increase these values to appropriate size 
-if the sound card is equipped with more DRAM.
-
-- AWE_MAX_SF_LISTS, AWE_MAX_SAMPLES, AWE_MAX_INFOS
-
-
-[Other Conditions]
-
-- AWE_ALWAYS_INIT_FM           (default: not defined)
-    indicates the AWE driver always initialize FM passthrough even
-    without DRAM on board.  Emu8000 chip has a restriction for playing
-    samples on DRAM that at least two channels must be occupied as
-    passthrough channels. 
-
-- AWE_DEBUG_ON                 (default: defined)
-    turns on debugging messages if defined.
-
-- AWE_HAS_GUS_COMPATIBILITY    (default: defined)
-    Enables GUS compatibility mode if defined, reading GUS patches and 
-    GUS control commands.  Define this option to use GMOD or other
-    GUS module players.
-
-- CONFIG_AWE32_MIDIEMU         (default: defined)
-    Adds a MIDI emulation device by Emu8000 wavetable.  The emulation
-    device can be accessed as an external MIDI, and sends the MIDI
-    control codes directly.  XG and GS sysex/NRPN are accepted.
-    No MIDI input is supported.
-
-- CONFIG_AWE32_MIXER           (default: not defined)
-    Adds a mixer device for AWE32 bass/treble equalizer control.
-    You can access this device using /dev/mixer?? (usually mixer01).
-
-- AWE_USE_NEW_VOLUME_CALC      (default: defined)
-    Use the new method to calculate the volume change as compatible
-    with DOS/Win drivers.  This option can be toggled via aweset
-    program, or drvmidi player.
-
-- AWE_CHECK_VTARGET            (default: defined)
-    Check the current volume target value when searching for an
-    empty channel to allocate a new voice.  This is experimentally
-    implemented in this version.  (probably, this option doesn't
-    affect the sound quality severely...)
-
-- AWE_ALLOW_SAMPLE_SHARING     (default: defined)
-   Allow sample sharing for differently loaded patches.
-   This function is available only together with awesfx-0.4.3p3.
-   Note that this is still an experimental option.
-
-- DEF_FM_CHORUS_DEPTH          (default: 0x10)
-    The default strength to be sent to the chorus effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-- DEF_FM_REVERB_DEPTH          (default: 0x10)
-    The default strength to be sent to the reverb effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-
-* ACKNOWLEDGMENTS
-
-Thanks to Witold Jachimczyk (witek@xfactor.wpi.edu) for much advice
-on programming of AWE32.  Much code is brought from his AWE32-native 
-MOD player, ALMP.
-The port of awedrv to FreeBSD is done by Randall Hopper
-(rhh@ct.picker.com).
-The new volume calculation routine was derived from Mark Weaver's
-ADIP compatible routines.
-I also thank linux-awe-ml members for their efforts
-to reboot their system many times :-)
-
-
-* TODO'S
-
-- Complete DOS/Win compatibility
-- DSP-like output
-
-
-* COPYRIGHT
-
-Copyright (C) 1996-1998 Takashi Iwai
-
-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., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront
deleted file mode 100644 (file)
index 16f57ea..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-            An OSS/Free Driver for WaveFront soundcards
-              (Turtle Beach Maui, Tropez, Tropez Plus)
-
-                    Paul Barton-Davis, July 1998
-
-                         VERSION 0.2.5
-
-Driver Status
--------------
-
-Requires: Kernel 2.1.106 or later (the driver is included with kernels
-2.1.109 and above)
-         
-As of 7/22/1998, this driver is currently in *BETA* state. This means
-that it compiles and runs, and that I use it on my system (Linux
-2.1.106) with some reasonably demanding applications and uses.  I
-believe the code is approaching an initial "finished" state that
-provides bug-free support for the Tropez Plus.
-
-Please note that to date, the driver has ONLY been tested on a Tropez
-Plus. I would very much like to hear (and help out) people with Tropez
-and Maui cards, since I think the driver can support those cards as
-well. 
-
-Finally, the driver has not been tested (or even compiled) as a static
-(non-modular) part of the kernel. Alan Cox's good work in modularizing
-OSS/Free for Linux makes this rather unnecessary.
-
-Some Questions
---------------
-
-**********************************************************************
-0) What does this driver do that the maui driver did not ?
-**********************************************************************
-
-* can fully initialize a WaveFront card from cold boot - no DOS 
-          utilities needed
-* working patch/sample/program loading and unloading (the maui
-      driver didn't document how to make this work, and assumed
-      user-level preparation of the patch data for writing
-      to the board. ick.)
-* full user-level access to all WaveFront commands
-* for the Tropez Plus, (primitive) control of the YSS225 FX processor
-* Virtual MIDI mode supported - 2 MIDI devices accessible via the
-          WaveFront's MPU401/UART emulation. One
-         accesses the WaveFront synth, the other accesses the
-         external MIDI connector. Full MIDI read/write semantics
-         for both devices.
-* OSS-compliant /dev/sequencer interface for the WaveFront synth,
-         including native and GUS-format patch downloading.
-* semi-intelligent patch management (prototypical at this point)
-
-**********************************************************************
-1) What to do about MIDI interfaces ?
-**********************************************************************
-
-The Tropez Plus (and perhaps other WF cards) can in theory support up
-to 2 physical MIDI interfaces. One of these is connected to the
-ICS2115 chip (the WaveFront synth itself) and is controlled by
-MPU/UART-401 emulation code running as part of the WaveFront OS.  The
-other is controlled by the CS4232 chip present on the board. However,
-physical access to the CS4232 connector is difficult, and it is
-unlikely (though not impossible) that you will want to use it.
-
-An older version of this driver introduced an additional kernel config
-variable which controlled whether or not the CS4232 MIDI interface was
-configured. Because of Alan Cox's work on modularizing the sound
-drivers, and now backporting them to 2.0.34 kernels, there seems to be
-little reason to support "static" configuration variables, and so this
-has been abandoned in favor of *only* module parameters. Specifying
-"mpuio" and "mpuirq" for the cs4232 parameter will result in the
-CS4232 MIDI interface being configured; leaving them unspecified will
-leave it unconfigured (and thus unusable).
-
-BTW, I have heard from one Tropez+ user that the CS4232 interface is
-more reliable than the ICS2115 one. I have had no problems with the
-latter, and I don't have the right cable to test the former one
-out. Reports welcome.
-
-**********************************************************************
-2) Why does line XXX of the code look like this .... ?
-**********************************************************************
-
-Either because it's not finished yet, or because you're a better coder
-than I am, or because you don't understand some aspect of how the card
-or the code works. 
-
-I absolutely welcome comments, criticisms and suggestions about the
-design and implementation of the driver. 
-
-**********************************************************************
-3) What files are included ?
-**********************************************************************
-
-   drivers/sound/README.wavefront       -- this file
-
-   drivers/sound/wavefront.patch       -- patches for the 2.1.106 sound drivers
-                                          needed to make the rest of this work
-                                          DO NOT USE IF YOU'VE APPLIED THEM 
-                                          BEFORE, OR HAVE 2.1.109 OR ABOVE
-
-   drivers/sound/wavfront.c             -- the driver
-   drivers/sound/ys225.h                -- data declarations for FX config
-   drivers/sound/ys225.c                -- data definitions for FX config
-   drivers/sound/wf_midi.c              -- the "uart401" driver 
-                                             to support virtual MIDI mode.
-   include/wavefront.h                  -- the header file
-   Documentation/sound/oss/Tropez+          -- short docs on configuration
-
-**********************************************************************
-4) How do I compile/install/use it ?
-**********************************************************************
-
-PART ONE: install the source code into your sound driver directory
-
-  cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux>
-  tar -zxvf <where-you-put/wavefront.tar.gz>
-
-PART TWO: apply the patches
-
-     DO THIS ONLY IF YOU HAVE A KERNEL VERSION BELOW 2.1.109
-     AND HAVE NOT ALREADY INSTALLED THE PATCH(ES).
-
-  cd drivers/sound
-  patch < wavefront.patch
-
-PART THREE: configure your kernel
-
-  cd <top of your kernel tree>
-  make xconfig (or whichever config option you use)
-
-         - choose YES for Sound Support              
-         - choose MODULE (M) for OSS Sound Modules
-         - choose MODULE(M) to YM3812/OPL3 support
-        - choose MODULE(M) for WaveFront support
-        - choose MODULE(M) for CS4232 support
-
-        - choose "N" for everything else (unless you have other
-             soundcards you want support for)
-
-
-   make boot
-   .
-   .
-   .
-   <whatever you normally do for a kernel install>
-   make modules
-   .
-   .
-   .
-   make modules_install
-
-Here's my autoconf.h SOUND section:
-
-/*
- * Sound
- */
-#define CONFIG_SOUND 1
-#undef  CONFIG_SOUND_OSS
-#define CONFIG_SOUND_OSS_MODULE 1
-#undef  CONFIG_SOUND_PAS
-#undef  CONFIG_SOUND_SB
-#undef  CONFIG_SOUND_ADLIB
-#undef  CONFIG_SOUND_GUS
-#undef  CONFIG_SOUND_MPU401
-#undef  CONFIG_SOUND_PSS
-#undef  CONFIG_SOUND_MSS
-#undef  CONFIG_SOUND_SSCAPE
-#undef  CONFIG_SOUND_TRIX
-#undef  CONFIG_SOUND_MAD16
-#undef  CONFIG_SOUND_WAVEFRONT
-#define CONFIG_SOUND_WAVEFRONT_MODULE 1
-#undef  CONFIG_SOUND_CS4232
-#define CONFIG_SOUND_CS4232_MODULE 1
-#undef  CONFIG_SOUND_MAUI
-#undef  CONFIG_SOUND_SGALAXY
-#undef  CONFIG_SOUND_OPL3SA1
-#undef  CONFIG_SOUND_SOFTOSS
-#undef  CONFIG_SOUND_YM3812
-#define CONFIG_SOUND_YM3812_MODULE 1
-#undef  CONFIG_SOUND_VMIDI
-#undef  CONFIG_SOUND_UART6850
-/*
- * Additional low level sound drivers
- */
-#undef  CONFIG_LOWLEVEL_SOUND
-
-************************************************************
-6) How do I configure my card ?
-************************************************************
-
-You need to edit /etc/modprobe.conf. Here's mine (edited to show the
-relevant details):
-
-  # Sound system
-  alias char-major-14-* wavefront
-  alias synth0 wavefront
-  alias mixer0 cs4232
-  alias audio0 cs4232
-  install wavefront /sbin/modprobe cs4232 && /sbin/modprobe -i wavefront && /sbin/modprobe opl3
-  options wavefront io=0x200 irq=9
-  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
-  options opl3 io=0x388
-
-Things to note: 
-
-       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
-       and "synthirq" cs4232 options.
-
-       you can do without the opl3 module if you don't
-       want to use the OPL/[34] FM synth on the soundcard
-
-       the opl3 io parameter is conventionally not adjustable.
-       In theory, any not-in-use IO port address would work, but
-       just use 0x388 and stick with the crowd.
-
-**********************************************************************
-7) What about firmware ?
-**********************************************************************
-
-Turtle Beach have not given me permission to distribute their firmware
-for the ICS2115. However, if you have a WaveFront card, then you
-almost certainly have the firmware, and if not, its freely available
-on their website, at:
-
-   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus 
-
-The file is called WFOS2001.MOT (for the Tropez+).
-
-This driver, however, doesn't use the pure firmware as distributed,
-but instead relies on a somewhat processed form of it. You can
-generate this very easily. Following an idea from Andrew Veliath's
-Pinnacle driver, the following flex program will generate the
-processed version:
-
----- cut here -------------------------
-%option main
-%%
-^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
-<<EOF>> { fputc ('\0', stdout); return; }
-\n {} 
-.  {}
----- cut here -------------------------
-
-To use it, put the above in file (say, ws.l) compile it like this:
-
-      shell> flex -ows.c ws.l
-      shell> cc -o ws ws.c
-      
-and then use it like this:
-
-    ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
-
-If you put it somewhere else, you'll always have to use the wf_ospath
-module parameter (see below) or alter the source code.
-
-**********************************************************************
-7) How do I get it working ?
-**********************************************************************
-
-Optionally, you can reboot with the "new" kernel (even though the only
-changes have really been made to a module).
-
-Then, as root do:
-
-     modprobe wavefront
-
-You should get something like this in /var/log/messages:
-
-    WaveFront: firmware 1.20 already loaded.
-
-or 
-
-    WaveFront: no response to firmware probe, assume raw.
-
-then:
-
-    WaveFront: waiting for memory configuration ...
-    WaveFront: hardware version 1.64
-    WaveFront: available DRAM 8191k
-    WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty
-    WaveFront: 128 programs slots in use
-    WaveFront: 256 patch slots filled, 142 in use
-
-The whole process takes about 16 seconds, the longest waits being
-after reporting the hardware version (during the firmware download),
-and after reporting program status (during patch status inquiry).  Its
-shorter (about 10 secs) if the firmware is already loaded (i.e. only
-warm reboots since the last firmware load).
-
-The "available DRAM" line will vary depending on how much added RAM
-your card has. Mine has 8MB.
-
-To check basically functionality, use play(1) or splay(1) to send a
-.WAV or other audio file through the audio portion. Then use playmidi
-to play a General MIDI file. Try the "-D 0" to hear the
-difference between sending MIDI to the WaveFront and using the OPL/3,
-which is the default (I think ...). If you have an external synth(s)
-hooked to the soundcard, you can use "-e" to route to the
-external synth(s) (in theory, -D 1 should work as well, but I think
-there is a bug in playmidi which prevents this from doing what it
-should). 
-
-**********************************************************************
-8) What are the module parameters ?
-**********************************************************************
-
-Its best to read wavefront.c for this, but here is a summary:
-
-integers: 
-         wf_raw  - if set, ignore apparent presence of firmware
-                   loaded onto the ICS2115, reset the whole
-                   board, and initialize it from scratch. (default = 0)
-
-          fx_raw  - if set, always initialize the YSS225 processor
-                   on the Tropez plus. (default = 1)
-
-          < The next 4 are basically for kernel hackers to allow
-           tweaking the driver for testing purposes. >             
-
-          wait_usecs        -  loop timer used when waiting for
-                              status conditions on the board. 
-                              The default is 150.
-
-          debug_default    - debugging flags. See sound/wavefront.h
-                            for WF_DEBUG_* values. Default is zero.
-                            Setting this allows you to debug the
-                            driver during module installation.
-strings:
-         ospath - path to get to the pre-processed OS firmware.
-                   (default: /etc/sound/wavefront.os)
-
-**********************************************************************
-9) Who should I contact if I have problems?
-**********************************************************************
-
-Just me: Paul Barton-Davis <pbd@op.net>
-
-
diff --git a/Documentation/sound/oss/es1370 b/Documentation/sound/oss/es1370
deleted file mode 100644 (file)
index 7b38b1a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-The second one goes to the mixer "synth" setting and supports
-only a limited set of sampling rates (44100, 22050, 11025, 5512).
-By setting lineout to 1 on the driver command line
-(eg. insmod es1370 lineout=1) it is even possible on some
-cards to convert the LINEIN jack into a second LINEOUT jack, thus
-making it possible to output four independent audio channels!
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx
deleted file mode 100644 (file)
index 87d7b7b..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-Beta release of the rme96xx (driver for RME 96XX cards like the 
-"Hammerfall" and the "Hammerfall light") 
-
-Important: The driver module has to be installed on a freshly rebooted system, 
-otherwise the driver might not be able to acquire its buffers.
-
-features:
-
- - OSS programming interface (i.e. runs with standard OSS soundsoftware) 
- - OSS/Multichannel interface (OSS multichannel is done by just aquiring
-   more than 2 channels). The driver does not use more than one device 
-   ( yet .. this feature may be implemented later ) 
- - more than one RME card supported
-
-The driver uses a specific multichannel interface, which I will document
-when the driver gets stable. (take a look at the defines in rme96xx.h,
-which adds blocked multichannel formats i.e instead of 
-lrlrlrlr --> llllrrrr  etc.
-
-Use the "rmectrl" programm to look at the status of the card .. 
-or use xrmectrl, a GUI interface for the ctrl program.
-
-What you can do with the rmectrl program is to set the stereo device for
-OSS emulation (e.g. if you use SPDIF out).
-
-You do:
-
-./ctrl offset 24 24
-
-which makes the stereo device use channels 25 and 26.
-
-Guenter Geiger <geiger@epy.co.at>
-
-copy the first part of the attached source code into rmectrl.c
-and the  second part into xrmectrl (or get the program from
-http://gige.xdv.org/pages/soft/pages/rme)
-
-to compile: gcc -o rmectrl rmectrl.c
------------------------------- snip ------------------------------------
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <linux/soundcard.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "rme96xx.h"
-
-/*
-  remctrl.c
-  (C) 2000 Guenter Geiger <geiger@debian.org>
-  HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-*/
-
-/* # define DEVICE_NAME "/dev/mixer" */
-# define DEVICE_NAME "/dev/mixer1"
-
-
-void usage(void)
-{
-     fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
-     fprintf(stderr,"where command is one of:\n");
-     fprintf(stderr,"  help                       show this help\n");
-     fprintf(stderr,"  status                     show status bits\n");
-     fprintf(stderr,"  control                    show control bits\n");
-     fprintf(stderr,"  mix                        show mixer/offset status\n");
-     fprintf(stderr,"  master <n>                 set sync master\n");
-     fprintf(stderr,"  pro <n>                    set spdif out pro\n");
-     fprintf(stderr,"  emphasis <n>               set spdif out emphasis\n");
-     fprintf(stderr,"  dolby <n>                  set spdif out no audio\n");
-     fprintf(stderr,"  optout <n>                 set spdif out optical\n");
-     fprintf(stderr,"  wordclock <n>              set sync wordclock\n");
-     fprintf(stderr,"  spdifin <n>                set spdif in (0=optical,1=coax,2=intern)\n");
-     fprintf(stderr,"  syncref <n>                set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
-     fprintf(stderr,"  adat1cd <n>                set ADAT1 on internal CD\n");
-     fprintf(stderr,"  offset <devnr> <in> <out>  set dev (0..3) offset (0..25)\n");
-     exit(-1);
-}
-
-
-int main(int argc, char* argv[])
-{
-     int cards;
-     int ret;
-     int i;
-     double ft;
-     int fd, fdwr;
-     int param,orig;
-     rme_status_t stat;
-     rme_ctrl_t ctrl;
-     char *device;
-     int argidx;
-
-     if (argc < 2)
-         usage();
-
-     if (*argv[1]=='/') {
-         device = argv[1];
-         argidx = 2;
-     }
-     else {
-         device = DEVICE_NAME;
-         argidx = 1;
-     }
-
-     fprintf(stdout,"mixer device %s\n",device);
-     if ((fd = open(device,O_RDONLY)) < 0) {
-         fprintf(stdout,"opening device failed\n");
-         exit(-1);
-     }
-
-     if ((fdwr = open(device,O_WRONLY)) < 0) {
-         fprintf(stdout,"opening device failed\n");
-         exit(-1);
-     }
-
-     if (argc < argidx+1)
-         usage();
-
-     if (!strcmp(argv[argidx],"help"))
-        usage();
-     if (!strcmp(argv[argidx],"-h"))
-        usage();
-     if (!strcmp(argv[argidx],"--help"))
-        usage();
-
-     if (!strcmp(argv[argidx],"status")) {
-         ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
-         fprintf(stdout,"stat.irq %d\n",stat.irq);
-         fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
-         fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
-         fprintf(stdout,"stat.wclock %d\n",stat.wclock);
-         fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
-         fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
-         fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
-         fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
-         fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
-         fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
-         fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
-         fprintf(stdout,"stat.bufid %d\n",stat.bufid);
-         fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"control")) {
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         fprintf(stdout,"ctrl.start %d\n",ctrl.start);
-         fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
-         fprintf(stdout,"ctrl.master %d\n",ctrl.master);
-         fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
-         fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
-         fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
-         fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
-         fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
-         fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
-         fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
-         fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
-         fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
-         fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
-         fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
-         fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
-         fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
-         fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
-         fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
-         fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"mix")) {
-         rme_mixer mix;
-         int i;
-
-         for (i=0; i<4; i++) {
-              mix.devnr = i;
-              ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
-              if (mix.devnr == i) {
-                   fprintf(stdout,"devnr %d\n",mix.devnr);
-                   fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
-                   fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
-              }
-         }
-         exit (0);
-     }
-
-/* the control flags */
-
-     if (argc < argidx+2)
-         usage();
-
-     if (!strcmp(argv[argidx],"master")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("master = %d\n",val);
-         ctrl.master = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"pro")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("pro = %d\n",val);
-         ctrl.pro = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"emphasis")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("emphasis = %d\n",val);
-         ctrl.emphasis = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"dolby")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("dolby = %d\n",val);
-         ctrl.dolby = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"optout")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("optout = %d\n",val);
-         ctrl.opt_out = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"wordclock")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("wordclock = %d\n",val);
-         ctrl.wordclock = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"spdifin")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("spdifin = %d\n",val);
-         ctrl.spdif_in = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"syncref")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("syncref = %d\n",val);
-         ctrl.sync_ref = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"adat1cd")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("adat1cd = %d\n",val);
-         ctrl.adat1_cd = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-/* setting offset */
-
-     if (argc < argidx+4)
-         usage();
-
-     if (!strcmp(argv[argidx],"offset")) {
-         rme_mixer mix;
-
-         mix.devnr = atoi(argv[argidx+1]);
-
-         mix.i_offset = atoi(argv[argidx+2]);
-         mix.o_offset = atoi(argv[argidx+3]);
-         ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
-         fprintf(stdout,"devnr %d\n",mix.devnr);
-         fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
-         fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
-         exit (0);
-     }
-
-     usage();
-     exit (0); /* to avoid warning */
-}
-
-
----------------------------- <snip> --------------------------------
-#!/usr/bin/wish
-
-# xrmectrl
-# (C) 2000 Guenter Geiger <geiger@debian.org>
-# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-
-#set defaults "-relief ridged"
-set CTRLPROG "./rmectrl"
-if {$argc} {
-    set CTRLPROG "$CTRLPROG $argv"
-}
-puts "CTRLPROG $CTRLPROG"
-
-frame .butts
-button .butts.exit -text "Exit" -command "exit" -relief ridge
-#button .butts.state -text "State" -command "get_all"
-
-pack .butts.exit -side left
-pack .butts -side bottom
-
-
-#
-# STATUS
-#
-
-frame .status
-
-# Sampling Rate
-
-frame .status.sr
-label .status.sr.text -text "Sampling Rate" -justify left
-radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
-radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
-radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
-radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw  -variable srate -value 96000 -font times
-
-pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
-
-# Lock
-
-frame .status.lock
-label .status.lock.text -text "Lock" -justify left
-checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
-checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
-checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
-
-pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
-
-# Sync
-
-frame .status.sync
-label .status.sync.text -text "Sync" -justify left
-checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
-checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
-checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
-
-pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
-
-# Timecode
-
-frame .status.tc
-label .status.tc.text -text "Timecode" -justify left
-checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
-checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
-checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
-
-pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
-
-# SPDIF In
-
-frame .status.spdif
-label .status.spdif.text -text "SPDIF In" -justify left
-label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
-checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
-
-pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
-
-pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
-
-
-#
-# CONTROL 
-#
-
-proc setprof {} {
-    global CTRLPROG
-    global spprof
-    exec $CTRLPROG pro $spprof
-}
-
-proc setemph {} {
-    global CTRLPROG
-    global spemph
-    exec $CTRLPROG emphasis $spemph
-}
-
-proc setnoaud {} {
-    global CTRLPROG
-    global spnoaud
-    exec $CTRLPROG dolby $spnoaud
-}
-
-proc setoptical {} {
-    global CTRLPROG
-    global spoptical
-    exec $CTRLPROG optout $spoptical
-}
-
-proc setspdifin {} {
-    global CTRLPROG
-    global spdifin
-    exec $CTRLPROG spdifin [expr $spdifin - 1]
-}
-
-proc setsyncsource {} {
-    global CTRLPROG
-    global syncsource
-    exec $CTRLPROG syncref [expr $syncsource -1]
-}
-
-
-proc setmaster {} {
-    global CTRLPROG
-    global master
-    exec $CTRLPROG master $master
-}
-
-proc setwordclock {} {
-    global CTRLPROG
-    global wordclock
-    exec $CTRLPROG wordclock $wordclock
-}
-
-proc setadat1cd {} {
-    global CTRLPROG
-    global adat1cd
-    exec $CTRLPROG adat1cd $adat1cd
-}
-
-
-frame .control
-
-# SPDIF In & SPDIF Out
-
-
-frame .control.spdif
-
-frame .control.spdif.in
-label .control.spdif.in.text -text "SPDIF In" -justify left
-radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
-
-checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
-
-pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
-
-label .control.spdif.space
-
-frame .control.spdif.out
-label .control.spdif.out.text -text "SPDIF Out" -justify left
-checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
-checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
-checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
-checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
-
-pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
-
-pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
-
-# Sync Mode & Sync Source
-
-frame .control.sync
-frame .control.sync.mode
-label .control.sync.mode.text -text "Sync Mode" -justify left
-checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
-checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
-
-pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
-
-label .control.sync.space
-
-frame .control.sync.src
-label .control.sync.src.text -text "Sync Source" -justify left
-radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
-radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
-
-pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
-
-pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
-
-label .control.space -text "" -width 10
-
-# Buffer Size
-
-frame .control.buf
-label .control.buf.text -text "Buffer Size (Latency)" -justify left
-radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
-radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
-radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
-radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
-radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
-radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
-radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
-radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
-
-pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 
-
-# Offset
-
-frame .control.offset
-
-frame .control.offset.in
-label .control.offset.in.text -text "Offset In" -justify left
-label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
-
-label .control.offset.space
-
-frame .control.offset.out
-label .control.offset.out.text -text "Offset Out" -justify left
-label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
-
-pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
-
-
-pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
-
-
-label .statustext -text Status -justify center -relief ridge
-label .controltext -text Control -justify center -relief ridge
-
-label .statusspace
-label .controlspace
-
-pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
-
-
-proc get_bit {output sstr} {
-    set idx1 [string last [concat $sstr 1] $output]
-    set idx1 [expr $idx1 != -1]
-    return $idx1
-}
-
-proc get_val {output sstr} {
-    set val [string wordend $output [string last $sstr $output]] 
-    set val [string range $output $val [expr $val+1]]
-    return $val
-}
-
-proc get_val2 {output sstr} {
-    set val [string wordend $output [string first $sstr $output]] 
-    set val [string range $output $val [expr $val+2]]
-    return $val
-}
-
-proc get_control {} {
-    global spprof
-    global spemph
-    global spnoaud
-    global spoptical
-    global spdifin
-    global ssrate
-    global master
-    global wordclock
-    global syncsource
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG control" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    set spprof [ get_bit $ooo "pro"]
-    set spemph [ get_bit $ooo "emphasis"]
-    set spnoaud [ get_bit $ooo "dolby"]
-    set spoptical [ get_bit $ooo "opt_out"]
-    set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
-    set ssrate [ expr [ get_val $ooo "latency"] + 1]
-    set master [ expr [ get_val $ooo "master"]]
-    set wordclock [ expr [ get_val $ooo "wordclock"]]
-    set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
-}
-
-proc get_status {} {
-    global srate
-    global ctrlcom
-
-    global adatlock1
-    global adatlock2
-    global adatlock3
-
-    global adatsync1
-    global adatsync2
-    global adatsync3
-
-    global tcbusy
-    global tcout
-    global tcvalid
-
-    global spdiferr
-    global crystal
-    global .status.spdif.text
-    global CTRLPROG
-
-
-    set f [open "| $CTRLPROG status" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-# samplerate
-
-    set idx1 [string last "sr48 1" $ooo]
-    set idx2 [string last "doublespeed 1" $ooo]
-    if {$idx1 >= 0} {
-       set fact1 48000
-    } else {
-       set fact1 44100
-    }
-
-    if {$idx2 >= 0} {
-       set fact2 2
-    } else {
-       set fact2 1
-    }
-    set srate [expr $fact1 * $fact2]
-#   ADAT lock
-
-    set val [get_val $ooo lockmask]
-    set adatlock1 0
-    set adatlock2 0
-    set adatlock3 0
-    if {[expr $val & 1]} {
-       set adatlock3 1
-    }
-    if {[expr $val & 2]} {
-       set adatlock2 1
-    }
-    if {[expr $val & 4]} {
-       set adatlock1 1
-    }
-
-#  ADAT sync
-    set val [get_val $ooo syncmask]
-    set adatsync1 0
-    set adatsync2 0
-    set adatsync3 0
-
-    if {[expr $val & 1]} {
-       set adatsync3 1
-    }
-    if {[expr $val & 2]} {
-       set adatsync2 1
-    }
-    if {[expr $val & 4]} {
-       set adatsync1 1
-    }
-
-# TC busy
-
-    set tcbusy [get_bit $ooo "busy"]
-    set tcout [get_bit $ooo "out"]
-    set tcvalid [get_bit $ooo "valid"]
-    set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
-
-#  000=64kHz, 100=88.2kHz, 011=96kHz
-#  111=32kHz, 110=44.1kHz, 101=48kHz
-
-    set val [get_val $ooo crystalrate]
-
-    set crystal "--.- kHz"
-    if {$val == 0} {
-        set crystal "64 kHz"
-    }
-    if {$val == 4} {
-        set crystal "88.2 kHz"
-    }
-    if {$val == 3} {
-        set crystal "96 kHz"
-    }
-    if {$val == 7} {
-        set crystal "32 kHz"
-    }
-    if {$val == 6} {
-        set crystal "44.1 kHz"
-    }
-    if {$val == 5} {
-        set crystal "48 kHz"
-    }
-    .status.spdif.sr configure -text $crystal
-}
-
-proc get_offset {} {
-    global inoffset
-    global outoffset
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG mix" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off0 configure -text "dev\#0: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off0 configure -text "dev\#0: $val"
-    } else {
-       .control.offset.in.off0 configure -text "dev\#0: -"
-       .control.offset.out.off0 configure -text "dev\#0: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off1 configure -text "dev\#1: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off1 configure -text "dev\#1: $val"
-    } else {
-       .control.offset.in.off1 configure -text "dev\#1: -"
-       .control.offset.out.off1 configure -text "dev\#1: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off2 configure -text "dev\#2: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off2 configure -text "dev\#2: $val"
-    } else {
-       .control.offset.in.off2 configure -text "dev\#2: -"
-       .control.offset.out.off2 configure -text "dev\#2: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off3 configure -text "dev\#3: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off3 configure -text "dev\#3: $val"
-    } else {
-       .control.offset.in.off3 configure -text "dev\#3: -"
-       .control.offset.out.off3 configure -text "dev\#3: -"
-    }
-}
-
-
-proc get_all {} {
-get_status
-get_control
-get_offset
-}
-
-# main
-while {1} {
-  after 200
-  get_all
-  update
-}
diff --git a/Documentation/sound/oss/solo1 b/Documentation/sound/oss/solo1
deleted file mode 100644 (file)
index 6f53d40..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-Recording
----------
-
-Recording does not work on the author's card, but there
-is at least one report of it working on later silicon.
-The chip behaves differently than described in the data sheet,
-likely due to a chip bug. Working around this would require
-the help of ESS (for example by publishing an errata sheet),
-but ESS has not done so so far.
-
-Also, the chip only supports 24 bit addresses for recording,
-which means it cannot work on some Alpha mainboards.
-
-
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (or later, available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card has an OPL compatible FM synthesizer.
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/sonicvibes b/Documentation/sound/oss/sonicvibes
deleted file mode 100644 (file)
index 84dee2e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card both has an OPL compatible FM synthesizer as well as
-a wavetable synthesizer.
-
-I haven't managed so far to get the OPL synth running.
-
-Using the wavetable synthesizer requires allocating
-1-4MB of physically contiguous memory, which isn't possible
-currently on Linux without ugly hacks like the bigphysarea
-patch. Therefore, the driver doesn't support wavetable
-synthesis.
-
-
-No support from S3
-------------------
-
-I do not get any support from S3. Therefore, the driver
-still has many problems. For example, although the manual
-states that the chip should be able to access the sample
-buffer anywhere in 32bit address space, I haven't managed to
-get it working with buffers above 16M. Therefore, the card
-has the same disadvantages as ISA soundcards.
-
-Given that the card is also very noisy, and if you haven't
-already bought it, you should strongly opt for one of the
-comparatively priced Ensoniq products.
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
index 32cd50478b369640297a46ceaca3a90b99a469eb..eed331c738a3a9873f449862ae2b8268cfbae304 100644 (file)
@@ -19,7 +19,7 @@ db16          ???
 no_wave_dma option
 
 This option defaults to a value of 0, which allows the Ultrasound wavetable
-DSP to use DMA for for playback and downloading samples. This is the same
+DSP to use DMA for playback and downloading samples. This is the same
 as the old behaviour. If set to 1, no DMA is needed for downloading samples,
 and allows owners of a GUS MAX to make use of simultaneous digital audio
 (/dev/dsp), MIDI, and wavetable playback.
index a6ea0a1df9e41b4658fc3b4d481be03a371ef6fc..4c6cbdb3c5480909844dfd773e394022c76a70b5 100644 (file)
@@ -12,7 +12,7 @@ boxes.
 
 The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
 codec chip.  The AD1843 is accessed through the Cobalt I/O ASIC, also
-known as Lithium.  This driver programs both both chips.
+known as Lithium.  This driver programs both chips.
 
 ==============================================================================
 QUICK CONFIGURATION
index 4b9351624f134ac0e51d398747a5e48e0e4faba4..8418d35484fc850b28ec0744a1b8aa4751d8d2b2 100644 (file)
@@ -25,8 +25,8 @@ the bits necessary to run your device.  The most commonly
 used members of this structure, and their typical usage,
 will be detailed below.
 
-       Here is a piece of skeleton code for perofming a device
-probe in an SBUS driverunder Linux:
+       Here is a piece of skeleton code for performing a device
+probe in an SBUS driver under Linux:
 
        static int __devinit mydevice_probe_one(struct sbus_dev *sdev)
        {
@@ -98,7 +98,7 @@ in your .remove method.
 
        Any memory allocated, registers mapped, IRQs registered,
 etc. must be undone by your .remove method so that all resources
-of your device are relased by the time it returns.
+of your device are released by the time it returns.
 
        You should _NOT_ use the for_each_sbus(), for_each_sbusdev(),
 and for_all_sbusdev() interfaces.  They are deprecated, will be
index 9c45f3df2e1844ca27ce38d88d74fb02678968ba..a1e0ee20f595cc5cf6fb94d5fd4b7caf1430e7f2 100644 (file)
@@ -124,12 +124,12 @@ use a value of 8.
 The "pxa2xx_spi_chip.timeout_microsecs" fields is used to efficiently handle
 trailing bytes in the SSP receiver fifo.  The correct value for this field is
 dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific
-slave device.  Please note the the PXA2xx SSP 1 does not support trailing byte
+slave device.  Please note that the PXA2xx SSP 1 does not support trailing byte
 timeouts and must busy-wait any trailing bytes.
 
 The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting
 into internal loopback mode.  In this mode the SSP controller internally
-connects the SSPTX pin the the SSPRX pin.  This is useful for initial setup
+connects the SSPTX pin to the SSPRX pin.  This is useful for initial setup
 testing.
 
 The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
@@ -208,7 +208,7 @@ DMA and PIO I/O Support
 -----------------------
 The pxa2xx_spi driver support both DMA and interrupt driven PIO message
 transfers.  The driver defaults to PIO mode and DMA transfers must enabled by
-setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and and
+setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
 ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero.  The DMA
 mode support both coherent and stream based DMA mappings.
 
index 068732d32276b1f32bf285c10522b7e103e781e4..72795796b13d64a4667ab233ebded8c2bcad4297 100644 (file)
@@ -262,7 +262,7 @@ NON-STATIC CONFIGURATIONS
 Developer boards often play by different rules than product boards, and one
 example is the potential need to hotplug SPI devices and/or controllers.
 
-For those cases you might need to use use spi_busnum_to_master() to look
+For those cases you might need to use spi_busnum_to_master() to look
 up the spi bus master, and will likely need spi_new_device() to provide the
 board info based on the board that was hotplugged.  Of course, you'd later
 call at least spi_unregister_device() when that board is removed.
@@ -322,7 +322,7 @@ As soon as it enters probe(), the driver may issue I/O requests to
 the SPI device using "struct spi_message".  When remove() returns,
 the driver guarantees that it won't submit any more such messages.
 
-  - An spi_message is a sequence of of protocol operations, executed
+  - An spi_message is a sequence of protocol operations, executed
     as one atomic sequence.  SPI driver controls include:
 
       + when bidirectional reads and writes start ... by how its
index e409e5d0748601db721967bbaf631a87e3020832..02a481225b0d497c9182bcc2bcf40bb06079b4d5 100644 (file)
@@ -4,7 +4,7 @@ Rules on what kind of patches are accepted, and which ones are not, into the
 "-stable" tree:
 
  - It must be obviously correct and tested.
- - It can not be bigger than 100 lines, with context.
+ - It cannot be bigger than 100 lines, with context.
  - It must fix only one thing.
  - It must fix a real bug that bothers people (not a, "This could be a
    problem..." type thing).
@@ -14,7 +14,7 @@ Rules on what kind of patches are accepted, and which ones are not, into the
    critical.
  - No "theoretical race condition" issues, unless an explanation of how the
    race can be exploited is also provided.
- - It can not contain any "trivial" fixes in it (spelling changes,
+ - It cannot contain any "trivial" fixes in it (spelling changes,
    whitespace cleanups, etc).
  - It must be accepted by the relevant subsystem maintainer.
  - It must follow the Documentation/SubmittingPatches rules.
index 544430e3998027f2c822ff4d27d9123e4d7f5c90..b60590eca18fbc168a6aaa1800cf1163b06111ac 100644 (file)
   13. What to do when UML doesn't work
 
      13.1 Strange compilation errors when you build from source
-     13.2 UML hangs on boot after mounting devfs
+     13.2 (obsolete)
      13.3 A variety of panics and hangs with /tmp on a reiserfs  filesystem
      13.4 The compile fails with errors about conflicting types for 'open', 'dup', and 'waitpid'
      13.5 UML doesn't work when /tmp is an NFS filesystem
   bug fixes and enhancements that have gone into subsequent releases.
 
 
-  If you build your own kernel, and want to boot it from one of the
-  filesystems distributed from this site, then, in nearly all cases,
-  devfs must be compiled into the kernel and mounted at boot time.  The
-  exception is the SuSE filesystem.  For this, devfs must either not be
-  in the kernel at all, or "devfs=nomount" must be on the kernel command
-  line.  Any disagreement between the kernel and the filesystem being
-  booted about whether devfs is being used will result in the boot
-  getting no further than single-user mode.
-
-
-  If you don't want to use devfs, you can remove the need for it from a
-  filesystem by copying /dev from someplace, making a bunch of /dev/ubd
-  devices:
-
-
-  UML# for i in 0 1 2 3 4 5 6 7; do mknod ubd$i b 98 $i; done
-
-
-
-
-  and changing /etc/fstab and /etc/inittab to refer to the non-devfs
-  devices.
-
-
-
   2\b2.\b.2\b2.\b.  C\bCo\bom\bmp\bpi\bil\bli\bin\bng\bg a\ban\bnd\bd i\bin\bns\bst\bta\bal\bll\bli\bin\bng\bg k\bke\ber\brn\bne\bel\bl m\bmo\bod\bdu\bul\ble\bes\bs
 
   UML modules are built in the same way as the native kernel (with the
   +\bo  None - device=none
 
 
-     This causes the device to disappear.  If you are using devfs, the
-     device will not appear in /dev.  If not, then attempts to open it
-     will return -ENODEV.
+     This causes the device to disappear.
 
 
 
 
   Note that the IP address you assign to the host end of the tap device
   must be different than the IP you assign to the eth device inside UML.
-  If you are short on IPs and don't want to comsume two per UML, then
+  If you are short on IPs and don't want to consume two per UML, then
   you can reuse the host's eth IP address for the host ends of the tap
   devices.  Internally, the UMLs must still get unique IPs for their eth
   devices.  You can also give the UMLs non-routable IPs (192.168.x.x or
   there are multiple COWs associated with a backing file, a -d merge of
   one of them will invalidate all of the others.  However, it is
   convenient if you're short of disk space, and it should also be
-  noticably faster than a non-destructive merge.
+  noticeably faster than a non-destructive merge.
 
 
 
 
 
 
-  1\b13\b3.\b.2\b2.\b.  U\bUM\bML\bL h\bha\ban\bng\bgs\bs o\bon\bn b\bbo\boo\bot\bt a\baf\bft\bte\ber\br m\bmo\bou\bun\bnt\bti\bin\bng\bg d\bde\bev\bvf\bfs\bs
-
-  The boot looks like this:
-
-
-       VFS: Mounted root (ext2 filesystem) readonly.
-       Mounted devfs on /dev
-
-
-
-
-  You're probably running a recent distribution on an old machine.  I
-  saw this with the RH7.1 filesystem running on a Pentium.  The shared
-  library loader, ld.so, was executing an instruction (cmove) which the
-  Pentium didn't support.  That instruction was apparently added later.
-  If you run UML under the debugger, you'll see the hang caused by one
-  instruction causing an infinite SIGILL stream.
-
-
-  The fix is to boot UML on an older filesystem.
-
-
-
   1\b13\b3.\b.3\b3.\b.  A\bA v\bva\bar\bri\bie\bet\bty\by o\bof\bf p\bpa\ban\bni\bic\bcs\bs a\ban\bnd\bd h\bha\ban\bng\bgs\bs w\bwi\bit\bth\bh /\b/t\btm\bmp\bp o\bon\bn a\ba r\bre\bei\bis\bse\ber\brf\bfs\bs  f\bfi\bil\ble\bes\bsy\bys\bs-\b-
   t\bte\bem\bm
 
 
   1\b13\b3.\b.5\b5.\b.  U\bUM\bML\bL d\bdo\boe\bes\bsn\bn'\b't\bt w\bwo\bor\brk\bk w\bwh\bhe\ben\bn /\b/t\btm\bmp\bp i\bis\bs a\ban\bn N\bNF\bFS\bS f\bfi\bil\ble\bes\bsy\bys\bst\bte\bem\bm
 
-  This seems to be a similar situation with the resierfs problem above.
+  This seems to be a similar situation with the ReiserFS problem above.
   Some versions of NFS seems not to handle mmap correctly, which UML
-  depends on.  The workaround is have /tmp be non-NFS directory.
+  depends on.  The workaround is have /tmp be non-NFS directory.
 
 
   1\b13\b3.\b.6\b6.\b.  U\bUM\bML\bL h\bha\ban\bng\bgs\bs o\bon\bn b\bbo\boo\bot\bt w\bwh\bhe\ben\bn c\bco\bom\bmp\bpi\bil\ble\bed\bd w\bwi\bit\bth\bh g\bgp\bpr\bro\bof\bf s\bsu\bup\bpp\bpo\bor\brt\bt
   n\bne\bet\bt
 
   If you can connect to the host, and the host can connect to UML, but
-  you can not connect to any other machines, then you may need to enable
+  you cannot connect to any other machines, then you may need to enable
   IP Masquerading on the host.  Usually this is only experienced when
   using private IP addresses (192.168.x.x or 10.x.x.x) for host/UML
   networking, rather than the public address space that your host is
   Chris Reahard built a specialized root filesystem for running a DNS
   server jailed inside UML.  It's available from the download
   <http://user-mode-linux.sourceforge.net/dl-sf.html>  page in the Jail
-  Filesysems section.
+  Filesystems section.
 
 
 
index 90a5e9e5bef1daa9d0f0621e209827f0d180f384..a8643513a5f6cb25851140c021aec4a671c8b62c 100644 (file)
@@ -260,7 +260,7 @@ items:
        a pointer to it.
 
   7.4) Appropriately modify architecture specific code to register the
-       the new system call.
+       new system call.
 
 8) Test Specification
 ---------------------
index a49e5f2c2b46e6a2f9947956d17d3a78e045e758..8ffce746d496fc41de3cfadf7ad02af5f7fa6637 100644 (file)
@@ -184,7 +184,7 @@ you can pass information to the completion handler.
 Note that even when an error (or unlink) is reported, data may have been
 transferred.  That's because USB transfers are packetized; it might take
 sixteen packets to transfer your 1KByte buffer, and ten of them might
-have transferred succesfully before the completion was called.
+have transferred successfully before the completion was called.
 
 
 NOTE:  ***** WARNING *****
index 8ef45ea8f6911976ddba61dfe1e134cade932283..737d6104c3f39fb294774fc5c16de0cb99612a58 100644 (file)
@@ -49,20 +49,6 @@ Abstract Control Model (USB CDC ACM) specification.
   Unfortunately many modems and most ISDN TAs use proprietary interfaces and
 thus won't work with this drivers. Check for ACM compliance before buying.
 
-  The driver (with devfs) creates these devices in /dev/usb/acm:
-
-       crw-r--r--   1 root     root     166,   0 Apr  1 10:49 0
-       crw-r--r--   1 root     root     166,   1 Apr  1 10:49 1
-       crw-r--r--   1 root     root     166,   2 Apr  1 10:49 2
-
-  And so on, up to 31, with the limit being possible to change in acm.c to up
-to 256, so you can use up to 256 USB modems with one computer (you'll need
-three USB cards for that, though).
-
-  If you don't use devfs, then you can create device nodes with the same
-minor/major numbers anywhere you want, but either the above location or
-/dev/usb/ttyACM0 is preferred.
-
   To use the modems you need these modules loaded:
 
        usbcore.ko
index 39c68f8c4e6c7cd8969fa1f0ae03a1afd1bcc424..9cf83e8c27b8f94208d7ad0ebc4587d82430164d 100644 (file)
@@ -126,7 +126,7 @@ one or more packets could finish before an error stops further endpoint I/O.
                        urb->transfer_flags.
 
 -ENODEV                        Device was removed.  Often preceded by a burst of
-                       other errors, since the hub driver does't detect
+                       other errors, since the hub driver doesn't detect
                        device removal events immediately.
 
 -EXDEV                 ISO transfer only partially completed
@@ -145,7 +145,7 @@ one or more packets could finish before an error stops further endpoint I/O.
 hardware problems such as bad devices (including firmware) or cables.
 
 (**) This is also one of several codes that different kinds of host
-controller use to to indicate a transfer has failed because of device
+controller use to indicate a transfer has failed because of device
 disconnect.  In the interval before the hub driver starts disconnect
 processing, devices may receive such fault reports for every request.
 
index cd6fb4b58e1fceaee50083312b4fd7816c8023c6..6a790754e963bacbd536b59e5c9b13ac24e21f83 100644 (file)
@@ -118,7 +118,7 @@ index, the ioctl returns -1 and sets errno to -EINVAL.
 HIDIOCGDEVINFO - struct hiddev_devinfo (read)
 Gets a hiddev_devinfo structure which describes the device.
 
-HIDIOCGSTRING - struct struct hiddev_string_descriptor (read/write)
+HIDIOCGSTRING - struct hiddev_string_descriptor (read/write)
 Gets a string descriptor from the device. The caller must fill in the
 "index" field to indicate which descriptor should be returned.
 
index cd806bfc8b81a42301be0130a741bb5b47f6343b..e43cfffaa1003691795d91134eb73302af5b6681 100644 (file)
@@ -11,7 +11,7 @@ CHANGES
    Changed reset from standard USB dev reset to vendor reset
    Changed data sent to host from compensated to raw coordinates
    Eliminated vendor/product module params
-   Performed multiple successfull tests with an EXII-5010UC
+   Performed multiple successful tests with an EXII-5010UC
 
 SUPPORTED HARDWARE:
 
@@ -38,7 +38,7 @@ This driver appears to be one of possible 2 Linux USB Input Touchscreen
 drivers.  Although 3M produces a binary only driver available for
 download, I persist in updating this driver since I would like to use the
 touchscreen for embedded apps using QTEmbedded, DirectFB, etc. So I feel the
-logical choice is to use Linux Imput.
+logical choice is to use Linux Input.
 
 Currently there is no way to calibrate the device via this driver.  Even if
 the device could be calibrated, the driver pulls to raw coordinate data from
@@ -63,7 +63,7 @@ TODO:
 Implement a control urb again to handle requests to and from the device
 such as calibration, etc once/if it becomes available.
 
-DISCLAMER:
+DISCLAIMER:
 
 I am not a MicroTouch/3M employee, nor have I ever been.  3M does not support 
 this driver!  If you want touch drivers only supported within X, please go to:
index a2dee6e6190d73e9c1c266cf3544a5e252e8b5eb..8dc2bacc8f1f4b6048ef99461df310330375a111 100644 (file)
@@ -13,7 +13,6 @@ CONFIGURATION
   Currently the driver can handle up to 256 different serial interfaces at
   one time. 
 
-  If you are not using devfs:
     The major number that the driver uses is 188 so to use the driver,
     create the following nodes:
        mknod /dev/ttyUSB0 c 188 0
@@ -26,10 +25,6 @@ CONFIGURATION
        mknod /dev/ttyUSB254 c 188 254
        mknod /dev/ttyUSB255 c 188 255
 
-  If you are using devfs:
-    The devices supported by this driver will show up as
-    /dev/usb/tts/{0,1,...}
-
   When the device is connected and recognized by the driver, the driver
   will print to the system log, which node(s) the device has been bound
   to.
@@ -228,7 +223,7 @@ Cypress M8 CY4601 Family Serial Driver
                -Cypress HID->COM RS232 adapter
        
                Note: Cypress Semiconductor claims no affiliation with the
-                       the hid->com device.
+                       hid->com device.
 
        Most devices using chipsets under the CY4601 family should
      work with the driver.  As long as they stay true to the CY4601
@@ -277,7 +272,7 @@ Digi AccelePort Driver
   work under SMP with the uhci driver.
 
   The driver is generally working, though we still have a few more ioctls
-  to implement and final testing and debugging to do.  The paralled port
+  to implement and final testing and debugging to do.  The parallel port
   on the USB 2 is supported as a serial to parallel converter; in other
   words, it appears as another USB serial port on Linux, even though
   physically it is really a parallel port.  The Digi Acceleport USB 8
@@ -427,7 +422,7 @@ Options supported:
   debug                        - extra verbose debugging info
                          (default: 0; nonzero enables)
   use_lowlatency       - use low_latency flag to speed up tty layer
-                         when reading from from the device.
+                         when reading from the device.
                          (default: 0; nonzero enables)
 
   See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
index c73a32c34528d8cac694b73f304a309f0481c19e..a4b7ae800866c4ad6411187d7a65e1f021f7bbe5 100644 (file)
@@ -155,7 +155,7 @@ Source file list / functional overview:
   pvrusb2-i2c-core.[ch] - This module provides an implementation of a
     kernel-friendly I2C adaptor driver, through which other external
     I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
-    operate corresponding chips within the the pvrusb2 device.  It is
+    operate corresponding chips within the pvrusb2 device.  It is
     through here that other V4L modules can reach into this driver to
     operate specific pieces (and those modules are in turn driven by
     glue logic which is coordinated by pvrusb2-hdw, doled out by
index 040a2c841ae96352365d0048c07744661de7b631..deb218f77adb05f427aa1b5a2437fc3ca010eb4b 100644 (file)
@@ -144,7 +144,7 @@ tv broadcast formats all aver the world.
 
 The CCIR defines parameters needed for broadcasting the signal.
 The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
-The CCIR says not much about about the colorsystem used !!!
+The CCIR says not much about the colorsystem used !!!
 And talking about a colorsystem says not to much about how it is broadcast.
 
 The CCIR standards A,E,F are not used any more.
index 9df4fb3ea0f2acaa253be746b515c0d0fcde6286..78bf5f21e513333e6c04b4369d9f6a1d9107fe0a 100644 (file)
@@ -102,7 +102,7 @@ Param[0]
 Name   CX2341X_DEC_GET_XFER_INFO
 Enum   9/0x09
 Description
-       This API call may be used to detect an end of stream condtion.
+       This API call may be used to detect an end of stream condition.
 Result[0]
        Stream type
 Result[1]
index 001c68644b081c7a4f5f620e31af85790acd4902..15df0df57dddb284974180e92d3b864b0f5661e1 100644 (file)
@@ -280,7 +280,7 @@ Param[0]
 Param[1]
        Unknown, but leaving this to 0 seems to work best. Indications are that
        this might have to do with USB support, although passing anything but 0
-       onl breaks things.
+       only breaks things.
 
 -------------------------------------------------------------------------------
 
index da98ae30a37a2ecd62c3d304115eb91483029625..0a602f3e601b1615ecb69e720e85c547e60f4f82 100644 (file)
@@ -97,7 +97,7 @@ Result[0]
 Result[1]
        top left vertical offset
 Result[2]
-       bottom right hotizontal offset
+       bottom right horizontal offset
 Result[3]
        bottom right vertical offset
 
index 93fec32a1188cbb19ff2ebca3807b11587516218..faccee68f6033b0ab8a2bda2aef08032ecad2c8e 100644 (file)
@@ -30,7 +30,7 @@ provide for a handler)
 GP_SAMPLE register is at 0x35C058
 
 Bits are then right shifted into the GP_SAMPLE register at the specified
-rate; you get an interrupt when a full DWORD is recieved.
+rate; you get an interrupt when a full DWORD is received.
 You need to recover the actual RC5 bits out of the (oversampled) IR sensor
 bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
 actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
index cd584f20a997df1fc9700824ad95a551a1ef16d1..1bdee8f85b9aa2ac2fe5e56fd8c3a2b4c64525f3 100644 (file)
@@ -80,7 +80,7 @@ Some of the features of the driver are:
   high compression quality (see also "Notes for V4L2 application developers"
   paragraph);
 - full support for the capabilities of every possible image sensors that can
-  be connected to the ET61X[12]51 bridges, including, for istance, red, green,
+  be connected to the ET61X[12]51 bridges, including, for instance, red, green,
   blue and global gain adjustments and exposure control (see "Supported
   devices" paragraph for details);
 - use of default color settings for sunlight conditions;
@@ -222,7 +222,7 @@ identifier - of the camera registered as "/dev/video0":
        [root@localhost #] echo 1 > i2c_reg
        [root@localhost #] cat i2c_val
 
-Note that if the sensor registers can not be read, "cat" will fail.
+Note that if the sensor registers cannot be read, "cat" will fail.
 To avoid race conditions, all the I/O accesses to the files are serialized.
 
 
index 93fec32a1188cbb19ff2ebca3807b11587516218..faccee68f6033b0ab8a2bda2aef08032ecad2c8e 100644 (file)
@@ -30,7 +30,7 @@ provide for a handler)
 GP_SAMPLE register is at 0x35C058
 
 Bits are then right shifted into the GP_SAMPLE register at the specified
-rate; you get an interrupt when a full DWORD is recieved.
+rate; you get an interrupt when a full DWORD is received.
 You need to recover the actual RC5 bits out of the (oversampled) IR sensor
 bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
 actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
index 2137da97552fb6743365ea25ae60a07dd88ce5d0..ecb34160e61d5ca2fafad4bba259b782199cc66e 100644 (file)
@@ -29,7 +29,7 @@ driver (PCI vendor/device is 0x136b/0xff01)
 
 The third one, present in recent (more or less last year) Picturebooks
 (C1M* models), is not supported. The manufacturer has given the specs
-to the developers under a NDA (which allows the develoment of a GPL
+to the developers under a NDA (which allows the development of a GPL
 driver however), but things are not moving very fast (see
 http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
 
index 1d20895b4354b99f2da591adac5027daec0253ff..8cda472db36db5241447bb8ac9f794c076d17a79 100644 (file)
@@ -60,7 +60,7 @@ It's worth to note that SONiX has never collaborated with the author during the
 development of this project, despite several requests for enough detailed
 specifications of the register tables, compression engine and video data format
 of the above chips. Nevertheless, these informations are no longer necessary,
-becouse all the aspects related to these chips are known and have been
+because all the aspects related to these chips are known and have been
 described in detail in this documentation.
 
 The driver relies on the Video4Linux2 and USB core modules. It has been
@@ -85,7 +85,7 @@ Some of the features of the driver are:
   high compression quality (see also "Notes for V4L2 application developers"
   and "Video frame formats" paragraphs);
 - full support for the capabilities of many of the possible image sensors that
-  can be connected to the SN9C10x bridges, including, for istance, red, green,
+  can be connected to the SN9C10x bridges, including, for instance, red, green,
   blue and global gain adjustments and exposure (see "Supported devices"
   paragraph for details);
 - use of default color settings for sunlight conditions;
index 0d53ce774b01c75b26d5fb2aff1ce1e9098071de..e0bba8393c7780b96bd278a63d749fea23e88b35 100644 (file)
@@ -15,7 +15,7 @@ Index
 5.  Supported devices
 6.  Module dependencies
 7.  Module loading
-8.  Module paramaters
+8.  Module parameters
 9.  Contact information
 10. Credits
 
index ac6d92d0194470170aa3c569b3de1179557efdb7..1a1c2d03a5c81fd6876ddb1d635068fa9feb21c5 100644 (file)
@@ -118,9 +118,9 @@ card is not there, please try if any other card gives some
 response, and mail me if you got a working tvcard addition.
 
 PS. <TVCard editors behold!)
-    Dont forget to set video_input to the number of inputs
+    Don't forget to set video_input to the number of inputs
     you defined in the video_mux part of the tvcard definition.
-    Its a common error to add a channel but not incrementing
+    It's a common error to add a channel but not incrementing
     video_input and getting angry with me/v4l/linux/linus :(
 
 You are now ready to test the framegrabber with your favorite
index 4b8db1bd3b78e5dd6b670f8a24afb11985070b21..e93ad9425e2a162b949b015c53da2b155a897b29 100644 (file)
@@ -22,7 +22,7 @@ The initial port includes NUMAizing the bootmem allocator code by
 encapsulating all the pieces of information into a bootmem_data_t
 structure. Node specific calls have been added to the allocator. 
 In theory, any platform which uses the bootmem allocator should 
-be able to to put the bootmem and mem_map data structures anywhere
+be able to put the bootmem and mem_map data structures anywhere
 it deems best.
 
 Each node's page allocation data structures have also been encapsulated
index 958ff3d48be3dd7288afa5e59b53cde05ccc8487..7e8ae83e9847bcdaad064cb1eaa2c0e609da4b66 100644 (file)
@@ -45,7 +45,7 @@ daemon and it crashes the system will not reboot.  Because of this,
 some of the drivers support the configuration option "Disable watchdog
 shutdown on close", CONFIG_WATCHDOG_NOWAYOUT.  If it is set to Y when
 compiling the kernel, there is no way of disabling the watchdog once
-it has been started.  So, if the watchdog dameon crashes, the system
+it has been started.  So, if the watchdog daemon crashes, the system
 will reboot after the timeout has passed.
 
 Some other drivers will not disable the watchdog, unless a specific
@@ -207,7 +207,7 @@ Note that not all devices support these two calls, and some only
 support the GETBOOTSTATUS call.
 
 Some drivers can measure the temperature using the GETTEMP ioctl.  The
-returned value is the temperature in degrees farenheit.
+returned value is the temperature in degrees fahrenheit.
 
     int temperature;
     ioctl(fd, WDIOC_GETTEMP, &temperature);
@@ -258,13 +258,13 @@ booke_wdt.c -- PowerPC BookE Watchdog Timer
        Timeout default varies according to frequency, supports
        SETTIMEOUT
 
-       Watchdog can not be turned off, CONFIG_WATCHDOG_NOWAYOUT
+       Watchdog cannot be turned off, CONFIG_WATCHDOG_NOWAYOUT
        does not make sense
 
        GETSUPPORT returns the watchdog_info struct, and
        GETSTATUS returns the supported options. GETBOOTSTATUS
        returns a 1 if the last reset was caused by the
-       watchdog and a 0 otherwise. This watchdog can not be
+       watchdog and a 0 otherwise. This watchdog cannot be
        disabled once it has been started. The wdt_period kernel
        parameter selects which bit of the time base changing
        from 0->1 will trigger the watchdog exception. Changing
index 74b77f9e91bc5cc5692eee19fc0b4b6be3a49302..f3c57f43ba6460e5b5927eaee2c86e2cfcaf5fa3 100644 (file)
@@ -109,7 +109,7 @@ Idle loop
 Rebooting
 
    reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
-   bios          Use the CPU reboto vector for warm reset
+   bios          Use the CPU reboot vector for warm reset
    warm   Don't set the cold reboot flag
    cold   Set the cold reboot flag
    triple Force a triple fault (init)
index 1c6223d3ce70b465561e41616e9aa2179c52972e..8c35b3c503aa842e0258a949f2ef8633e541db01 100644 (file)
@@ -977,6 +977,13 @@ L: ebtables-devel@lists.sourceforge.net
 W:     http://ebtables.sourceforge.net/
 S:     Maintained
 
+ECRYPT FILE SYSTEM
+P:     Mike Halcrow, Phillip Hellewell
+M:     mhalcrow@us.ibm.com, phillip@hellewell.homeip.net
+L:     ecryptfs-devel@lists.sourceforge.net
+W:     http://ecryptfs.sourceforge.net/
+S:     Supported
+
 EDAC-CORE
 P:     Doug Thompson
 M:     norsk5@xmission.com
@@ -1893,11 +1900,6 @@ M:       rroesler@syskonnect.de
 W:     http://www.syskonnect.com
 S:     Supported
 
-MAESTRO PCI SOUND DRIVERS
-P:     Zach Brown
-M:     zab@zabbo.net
-S:     Odd Fixes
-
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 P: Michael Kerrisk
 M: mtk-manpages@gmx.net
@@ -2434,6 +2436,19 @@ M:       mporter@kernel.crashing.org
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+READ-COPY UPDATE (RCU)
+P:     Dipankar Sarma
+M:     dipankar@in.ibm.com
+W:     http://www.rdrop.com/users/paulmck/rclock/
+L:     linux-kernel@vger.kernel.org
+S:     Supported
+
+RCUTORTURE MODULE
+P:     Josh Triplett
+M:     josh@freedesktop.org
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
+
 REAL TIME CLOCK DRIVER
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
@@ -2854,6 +2869,11 @@ M:       hlhung3i@gmail.com
 W:     http://tcp-lp-mod.sourceforge.net/
 S:     Maintained
 
+TI FLASH MEDIA INTERFACE DRIVER
+P:      Alex Dubov
+M:      oakad@yahoo.com
+S:      Maintained
+
 TI OMAP RANDOM NUMBER GENERATOR SUPPORT
 P:     Deepak Saxena
 M:     dsaxena@plexity.net
@@ -3377,12 +3397,6 @@ M:       Henk.Vergonet@gmail.com
 L:     usbb2k-api-dev@nongnu.org
 S:     Maintained
 
-YMFPCI YAMAHA PCI SOUND (Use ALSA instead)
-P:     Pete Zaitcev
-M:     zaitcev@yahoo.com
-L:     linux-kernel@vger.kernel.org
-S:     Obsolete
-
 Z8530 DRIVER FOR AX.25
 P:     Joerg Reuter
 M:     jreuter@yaina.de
index 4c6c5e32ef96e3d12da975e682ee8a3f6ebc37e3..adb2c748e105609e2f37b91318e87c90bb189961 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1321,7 +1321,7 @@ define xtags
                --langdef=kconfig \
                --language-force=kconfig \
                --regex-kconfig='/^[[:blank:]]*config[[:blank:]]+([[:alnum:]_]+)/\1/'; \
-           $(all-defconfigs) | xargs $1 -a \
+           $(all-defconfigs) | xargs -r $1 -a \
                --langdef=dotconfig \
                --language-force=dotconfig \
                --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \
@@ -1329,7 +1329,7 @@ define xtags
            $(all-sources) | xargs $1 -a; \
            $(all-kconfigs) | xargs $1 -a \
                --regex='/^[ \t]*config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
-           $(all-defconfigs) | xargs $1 -a \
+           $(all-defconfigs) | xargs -r $1 -a \
                --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
        else \
            $(all-sources) | xargs $1 -a; \
index 2b36afd8e969e479d88458bd5d092a4aa898c4cb..7e55ea66c6d4ad1e41fdaa02ae09c3aabf1991b1 100644 (file)
@@ -534,7 +534,7 @@ config ARCH_DISCONTIGMEM_ENABLE
        bool "Discontiguous Memory Support (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        help
-         Say Y to upport efficient handling of discontiguous physical memory,
+         Say Y to support efficient handling of discontiguous physical memory,
          for architectures which are either NUMA (Non-Uniform Memory Access)
          or have huge holes in the physical address space for other reasons.
          See <file:Documentation/vm/numa> for more.
index dbe327d32b6f03327fdab830d405c11a7bcf87f4..8b02420f732eb8e1df10db233b2444d9881470b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/alpha/kernel/ksyms.c
+ * linux/arch/alpha/kernel/alpha_ksyms.c
  *
  * Export the alpha-specific functions that are needed for loadable
  * modules.
index 1e2a62a1f75fbd3172b3b74d5fe42826c7804981..e27d23c74ba8172e2b4be60bb21e3880060101fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * alpha/boot/head.S
+ * arch/alpha/kernel/head.S
  *
  * initial boot stuff.. At this point, the bootloader has already
  * switched into OSF/1 PAL-code, and loaded us at the correct address
index 08b8302e64ca0f9630ffddfb2585d5a4915adfda..0caa45aa128d773aa470bbd3fd753c75e92429e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     linux/arch/alpha/kernel/machvec.h
+ *     linux/arch/alpha/kernel/machvec_impl.h
  *
  *     Copyright (C) 1997, 1998  Richard Henderson
  *
index 3c1f3e6522e5d59aa9c2b290b7095b02c90108f5..78f6b924ad8f18f5502b555b4a58b85b5748be44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/alpha/lib/stackcheck.S
+ * arch/alpha/lib/dbg_stackcheck.S
  * Contributed by Richard Henderson (rth@tamu.edu)
  *
  * Verify that we have not overflowed the stack.  Oops if we have.
index e9f6a9dcf2b7c31bc947127422bf0fd7d9462072..c1e40a1a43d5f82d9b9f556341b7bc21f189912e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/alpha/lib/killstack.S
+ * arch/alpha/lib/dbg_stackkill.S
  * Contributed by Richard Henderson (rth@cygnus.com)
  *
  * Clobber the balance of the kernel stack, hoping to catch
index 8ff6e7e1773e0fc649914b04844b2737fe284870..311b8cfc691488743d178c2dd79eb9f7edafbd81 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/alpha/memset.S
+ * linux/arch/alpha/lib/memset.S
  *
  * This is an efficient (and small) implementation of the C library "memset()"
  * function for the alpha.
index f9362ee9955f2411e932dbdca13a9dab5bf2c364..adb05de40e24e80ade661f678108e35242872de5 100644 (file)
@@ -629,7 +629,7 @@ config ALIGNMENT_TRAP
        depends on CPU_CP15_MMU
        default y if !ARCH_EBSA110
        help
-         ARM processors can not fetch/store information which is not
+         ARM processors cannot fetch/store information which is not
          naturally aligned on the bus, i.e., a 4 byte fetch must start at an
          address divisible by 4. On 32-bit ARM processors, these non-aligned
          fetch/store instructions will be emulated in software if you say
index 941c5f5cbacf9a2492edbc96a95d348be7b718f2..4f3c78ac30a0d7ea42a99cb3aae8ab749f96acde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/boot/compressed/head.S
+ * linux/arch/arm/boot/compressed/head-clps7500.S
  *
  * Copyright (C) 1999, 2000, 2001 Nexus Electronics Ltd
  */
index 29818bd3248f1f6b1caa39b4320f212ab4eb46cc..30046ad41cedd52fd3884deced4a242f1a5186d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-sa1100/sa1111.c
+ * linux/arch/arm/common/sa1111.c
  *
  * SA1111 support
  *
index 471c1db7c57f0971b444199093cd261aa8baf922..cf30803e019be4329202d8744736d1a9b8d5bd66 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-imx/leds.h
+ * linux/arch/arm/mach-imx/leds.c
  *
  * Copyright (C) 2004 Sascha Hauer <sascha@saschahauer.de>
  *
index 83fa21e795a999ce97f515d3bd8947dfbbf2cbe8..49dc1c1da33884b8f28dd3170af0f821f06b33c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-imx/leds.h
+ * arch/arm/mach-imx/leds.h
  *
  * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
  *
index 2cebb2878895bdb0afc2a0707caf3bfde91bba57..7bc94f3def1c8dc8d3b882de548747ced6c99c79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arch/mach-ixp4xx/coyote-pci.c
+ * arch/arm/mach-ixp4xx/coyote-pci.c
  *
  * PCI setup routines for ADI Engineering Coyote platform
  *
index ed52708002174e222f635ef3c701fc1b8dbabbf7..509a95a692a419b569a8514bc08cb87434f39031 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arch/mach-ixp4xx/ixdpg425-pci.c
+ * arch/arm/mach-ixp4xx/ixdpg425-pci.c
  *
  * PCI setup routines for Intel IXDPG425 Platform
  *
index a6910114b24c5d9cd4e46a299c97a0f8bfb1547a..a21b12f06c6b3aa2be8bf6ed66809212b036d6a4 100644 (file)
@@ -164,7 +164,7 @@ static void lh7a40x_ack_cpld_irq (u32 irq)
        /* CPLD doesn't have ack capability, but some devices may */
 
 #if defined (CPLD_INTMASK_TOUCH)
-       /* The touch control *must* mask the the interrupt because the
+       /* The touch control *must* mask the interrupt because the
         * interrupt bit is read by the driver to determine if the pen
         * is still down. */
        if (irq == IRQ_TOUCH)
index 976edfb882e2a9f6a46d7f26dded21c75e4ff1f4..c4b790217a5b0ab259ac8289d4a415ef578e81ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap1/id.c
+ * linux/arch/arm/mach-omap1/serial.c
  *
  * OMAP1 CPU identification code
  *
index 2db6b732b084837fe29e7f4d5f7213b213c88ee9..c37b0e6d12481388335b96992845132dc7f32925 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-apollon.c
+ * linux/arch/arm/mach-omap2/board-apollon.c
  *
  * Copyright (C) 2005,2006 Samsung Electronics
  * Author: Kyungmin Park <kyungmin.park@samsung.com>
index eaecbf422d8c825eb49f8b8c373d9914c3cfb598..90938151bcf1340df536283c8b1053c5f0b50655 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-generic.c
+ * linux/arch/arm/mach-omap2/board-generic.c
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
index 996aeda1285d058e6abe2b39df36bfb5bbcf75b1..26a95a642ad7a1f4dde8227b034f22120ba554b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/board-h4.c
+ * linux/arch/arm/mach-omap2/board-h4.c
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
index 1ed2fff4691a348b38faa68e4cff766bf0203e46..11870093d7a1159f41022f747a328c1fa938eda4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap/omap2/irq.c
+ * linux/arch/arm/mach-omap2/irq.c
  *
  * Interrupt handler for OMAP2 boards.
  *
index 22ac7be4f78289f17670b690c887f6cd058c9167..5e1c4b53ee9de1af966f138f77758b132c46bd8d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap2/prcm-reg.h
+ * linux/arch/arm/mach-omap2/prcm-regs.h
  *
  * OMAP24XX Power Reset and Clock Management (PRCM) registers
  *
index 0884bc7c23b7f31635266ff8a10c0c15cb701e61..aaa5589e8169845e97e0d63f7d6db2b65dee2e1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-omap/omap2/serial.c
+ * arch/arm/mach-omap2/serial.c
  *
  * OMAP2 serial support.
  *
index a5ef7f611da95e27296648112cb335dec50aa6b0..b27576690f8df1c3a18e1831af4228b9465dd631 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap2/sram.S
+ * linux/arch/arm/mach-omap2/sram-fn.S
  *
  * Omap2 specific functions that need to be run in internal SRAM
  *
index d7815491b752cb3e344bff363cb023c2adf7ea8c..a72476c24621a1fda23ca50e3242236df8c0c1ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/video/w100fb.c
+ * linux/arch/arm/mach-pxa/corgi_lcd.c
  *
  * Corgi/Spitz LCD Specific Code
  *
index 4f829b8c39dd0a30d93a2d04de4d0d920fb3a2ee..7f0dfe01345a56875978b33522650b7fdc2a4c40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-pxa/leds.h
+ * arch/arm/mach-pxa/leds.h
  *
  * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
  *
index df37594c30f83baef8a80d54b218ed56c83e4929..63965c78de8c652be823c23b9de504231c1a6479 100644 (file)
@@ -13,7 +13,7 @@ config MACH_ANUBIS
        bool "Simtec Electronics ANUBIS"
        select CPU_S3C2440
        help
-         Say Y gere if you are using the Simtec Electronics ANUBIS
+         Say Y here if you are using the Simtec Electronics ANUBIS
          development system
 
 config MACH_OSIRIS
index f2a78175a70a07efc40f1d24a2a8e3b785a88088..1576d01d5f829bb31ec78ec2976acf6e3443f41e 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/gpio.c
+/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c
  *
  * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
  *
index 99718663318e74dc2f9eca1bb5ae066f500853e3..00abe199a08eca05ac62644f85a49666e0fbd0ee 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/clock.c
+/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index 471a714900103c55c034d6c396f5c6cb9ad2b082..a2098f692d83fb13b8d8ad4d956a53bbca47690b 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/gpio.c
+/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
  *
  * Copyright (c) 2004-2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index debae24305579f97eb5969e06a158158e329bc6f..581667efd13c8f8c84af03b80b00796a8ac6482d 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440.c
+/* linux/arch/arm/mach-s3c2410/s3c2442.c
  *
  * Copyright (c) 2006 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
index 0d13546c350005152d330b193fdf135f72605ade..ec702f88b299f051f65e87d7d3f3f7011455bca2 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
+/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c
  *
  * Copyright (c) 2003,2004 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index 3e7f5f75134d4c2f867b5bef7ba55f1fea241f26..1488c1eb37e67cf56c4c929d6722e1d5af3610e8 100644 (file)
@@ -1,4 +1,4 @@
-/* arch/arm/mach-s3c2410/s3c2440.h
+/* arch/arm/mach-s3c2410/s3c244x.h
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index 92c0cc83aeecf1c1d1f936d051b8027cf985d9d7..d8aa6127dedb6826e4068ce637895b26d8074fe2 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/usb-simtec.c
+/* linux/arch/arm/mach-s3c2410/usb-simtec.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
index 3c6441d4bc598421323556c804aee770f6cb6d60..2ea2a657a0346c06a2bf293814cf7e7ef95079bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arm/kernel/dma-sa1100.c
+ * arch/arm/mach-sa1100/dma.c
  *
  * Support functions for the SA11x0 internal DMA channels.
  *
index 7cd86d357a3c1901a9e3df08a90e62771164d3db..5386a81f796a07a9bbbd5eb89e9c7e24daba88d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arm/kernel/leds-shark.c
+ * arch/arm/mach-shark/leds.c
  * by Alexander Schulz
  *
  * derived from:
index 85cffe2c6266366d65a4ca8a963f729123879785..9e1813c77e05bf4ad44c1a347432f92fea3c5e5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/plat-omap/sram.S
+ * linux/arch/arm/plat-omap/sram-fn.S
  *
  * Functions that need to be run in internal SRAM
  *
index 8b50e8402954072af34fffe3a2f984f03b2663c2..734d5f3a530411ef71450325de866394daca1055 100644 (file)
@@ -550,7 +550,7 @@ config ETRAX_IDE
        select BLK_DEV_IDEDMA
        help
          Enable this to get support for ATA/IDE.
-         You can't use paralell ports or SCSI ports
+         You can't use parallel ports or SCSI ports
          at the same time.
 
 
@@ -744,7 +744,7 @@ config ETRAX_PA_CHANGEABLE_BITS
        default "FF"
        help
          This is a bitmask with information of what bits in PA that a user
-         can change change the value on using ioctl's.
+         can change the value on using ioctl's.
          Bit set = changeable.
          You probably want 00 here.
 
index 22f0ddc04c5054465fe52455d7bab99fc26befe1..4f79d8ed3e1c451ec122f0b29f93549f9cb3e166 100644 (file)
@@ -162,7 +162,7 @@ config ETRAX_SDRAM_GRP1_CONFIG
        depends on ETRAX_ARCH_V32
        default "0"
        help
-         SDRAM configuration for group 1. The defult value is 0
+         SDRAM configuration for group 1. The default value is 0
          because group 1 is not used in the default configuration,
          described in the help for SDRAM_GRP0_CONFIG.
 
index 1488b6ace18c3220ea22cd7cffe428e511b73520..1bfc77e391d5ade64e9b71c7848c804d5022f2b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/h8300/platform/h8300h/ints.c
+ * linux/arch/h8300/kernel/ints.c
  *
  * Yoshinori Sato <ysato@users.sourceforge.jp>
  *
index af219e51734fce97abd64b534746aff04cd30dbc..8ff1c6fb5aa135b678a3aa83047c1e57422ae6f8 100644 (file)
@@ -682,7 +682,7 @@ config EFI
        depends on ACPI
        default n
        ---help---
-       This enables the the kernel to boot on EFI platforms using
+       This enables the kernel to boot on EFI platforms using
        system configuration information passed to it from the firmware.
        This also enables the kernel to use any EFI runtime services that are
        available (such as the EFI variable services).
index 1aaea6ab8c463dec58d53c3a861d44a909fbc9e4..92f79cdd9a48c97aebb8a207a211cf28e421707a 100644 (file)
@@ -62,8 +62,6 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return
 #include <mach_mpparse.h>
 #endif                         /* CONFIG_X86_LOCAL_APIC */
 
-static inline int gsi_irq_sharing(int gsi) { return gsi; }
-
 #endif                         /* X86 */
 
 #define BAD_MADT_ENTRY(entry, end) (                                       \
@@ -468,12 +466,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-#ifdef CONFIG_X86_IO_APIC
-       if (use_pci_vector() && !platform_legacy_irq(gsi))
-               *irq = IO_APIC_VECTOR(gsi);
-       else
-#endif
-               *irq = gsi_irq_sharing(gsi);
+       *irq = gsi;
        return 0;
 }
 
index b2f24d57fddd25254eab6f832ffb3304cab80c84..d9f3e3c31f054240c790bbb461c8f261f2726487 100644 (file)
@@ -669,8 +669,7 @@ old_gdt:
         */
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
-       if (current->mm)
-               BUG();
+       BUG_ON(current->mm);
        enter_lazy_tlb(&init_mm, current);
 
        load_esp0(t, thread);
index f9436989473c23fa0f57ac4ddea21dc8a2f117f0..8b40648d0ef00f2570ea2f19e07da3e1f851d41f 100644 (file)
@@ -498,8 +498,7 @@ void __init efi_enter_virtual_mode(void)
                check_range_for_systab(md);
        }
 
-       if (!efi.systab)
-               BUG();
+       BUG_ON(!efi.systab);
 
        status = phys_efi_set_virtual_address_map(
                        memmap.desc_size * memmap.nr_map,
index ea5f4e7958d8f072108576fb33000af089d93ab0..d07ed31f11e3269aed95d97c7cb8784c00cd3c11 100644 (file)
  * moves to arch independent land
  */
 
-DEFINE_SPINLOCK(i8259A_lock);
-
-static void end_8259A_irq (unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
-                                                       irq_desc[irq].action)
-               enable_8259A_irq(irq);
-}
-
-#define shutdown_8259A_irq     disable_8259A_irq
-
 static int i8259A_auto_eoi;
-
+DEFINE_SPINLOCK(i8259A_lock);
 static void mask_and_ack_8259A(unsigned int);
 
-unsigned int startup_8259A_irq(unsigned int irq)
-{ 
-       enable_8259A_irq(irq);
-       return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type i8259A_irq_type = {
-       .typename = "XT-PIC",
-       .startup = startup_8259A_irq,
-       .shutdown = shutdown_8259A_irq,
-       .enable = enable_8259A_irq,
-       .disable = disable_8259A_irq,
-       .ack = mask_and_ack_8259A,
-       .end = end_8259A_irq,
+static struct irq_chip i8259A_chip = {
+       .name           = "XT-PIC",
+       .mask           = disable_8259A_irq,
+       .unmask         = enable_8259A_irq,
+       .mask_ack       = mask_and_ack_8259A,
 };
 
 /*
@@ -133,7 +113,7 @@ void make_8259A_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
        io_apic_irqs &= ~(1<<irq);
-       irq_desc[irq].chip = &i8259A_irq_type;
+       set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
        enable_irq(irq);
 }
 
@@ -327,12 +307,12 @@ void init_8259A(int auto_eoi)
        outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
        if (auto_eoi)
                /*
-                * in AEOI mode we just have to mask the interrupt
+                * In AEOI mode we just have to mask the interrupt
                 * when acking.
                 */
-               i8259A_irq_type.ack = disable_8259A_irq;
+               i8259A_chip.mask_ack = disable_8259A_irq;
        else
-               i8259A_irq_type.ack = mask_and_ack_8259A;
+               i8259A_chip.mask_ack = mask_and_ack_8259A;
 
        udelay(100);            /* wait for 8259A to initialize */
 
@@ -389,12 +369,13 @@ void __init init_ISA_irqs (void)
                        /*
                         * 16 old-style INTA-cycle interrupts:
                         */
-                       irq_desc[i].chip = &i8259A_irq_type;
+                       set_irq_chip_and_handler(i, &i8259A_chip,
+                                                handle_level_irq);
                } else {
                        /*
                         * 'high' PCI IRQs filled in on demand
                         */
-                       irq_desc[i].chip = &no_irq_type;
+                       irq_desc[i].chip = &no_irq_chip;
                }
        }
 }
index fd0df75cfbdadd3fd19afd2f5aeaf0308d9e96ba..b7287fb499f3f0537b1afd2111e3788976f94aa7 100644 (file)
@@ -31,6 +31,9 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/sysdev.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/htirq.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -38,6 +41,8 @@
 #include <asm/timer.h>
 #include <asm/i8259.h>
 #include <asm/nmi.h>
+#include <asm/msidef.h>
+#include <asm/hypertransport.h>
 
 #include <mach_apic.h>
 #include <mach_apicdef.h>
@@ -86,15 +91,6 @@ static struct irq_pin_list {
        int apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-#ifdef CONFIG_PCI_MSI
-#define vector_to_irq(vector)  \
-       (platform_legacy_irq(vector) ? vector : vector_irq[vector])
-#else
-#define vector_to_irq(vector)  (vector)
-#endif
-
-
 union entry_union {
        struct { u32 w1, w2; };
        struct IO_APIC_route_entry entry;
@@ -280,7 +276,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
                        break;
                entry = irq_2_pin + entry->next;
        }
-       set_irq_info(irq, cpumask);
+       set_native_irq_info(irq, cpumask);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -1181,46 +1177,45 @@ static inline int IO_APIC_irq_trigger(int irq)
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
 u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
 
-int assign_irq_vector(int irq)
+static int __assign_irq_vector(int irq)
 {
        static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-       unsigned long flags;
        int vector;
 
-       BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
+       BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
-       spin_lock_irqsave(&vector_lock, flags);
-
-       if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
-               spin_unlock_irqrestore(&vector_lock, flags);
+       if (IO_APIC_VECTOR(irq) > 0)
                return IO_APIC_VECTOR(irq);
-       }
-next:
+
        current_vector += 8;
        if (current_vector == SYSCALL_VECTOR)
-               goto next;
+               current_vector += 8;
 
        if (current_vector >= FIRST_SYSTEM_VECTOR) {
                offset++;
-               if (!(offset%8)) {
-                       spin_unlock_irqrestore(&vector_lock, flags);
+               if (!(offset % 8))
                        return -ENOSPC;
-               }
                current_vector = FIRST_DEVICE_VECTOR + offset;
        }
 
        vector = current_vector;
-       vector_irq[vector] = irq;
-       if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = vector;
+       IO_APIC_VECTOR(irq) = vector;
+
+       return vector;
+}
+
+static int assign_irq_vector(int irq)
+{
+       unsigned long flags;
+       int vector;
 
+       spin_lock_irqsave(&vector_lock, flags);
+       vector = __assign_irq_vector(irq);
        spin_unlock_irqrestore(&vector_lock, flags);
 
        return vector;
 }
-
-static struct hw_interrupt_type ioapic_level_type;
-static struct hw_interrupt_type ioapic_edge_type;
+static struct irq_chip ioapic_chip;
 
 #define IOAPIC_AUTO    -1
 #define IOAPIC_EDGE    0
@@ -1228,16 +1223,14 @@ static struct hw_interrupt_type ioapic_edge_type;
 
 static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
-       unsigned idx;
-
-       idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
-
        if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                        trigger == IOAPIC_LEVEL)
-               irq_desc[idx].chip = &ioapic_level_type;
+               set_irq_chip_and_handler(irq, &ioapic_chip,
+                                        handle_fasteoi_irq);
        else
-               irq_desc[idx].chip = &ioapic_edge_type;
-       set_intr_gate(vector, interrupt[idx]);
+               set_irq_chip_and_handler(irq, &ioapic_chip,
+                                        handle_edge_irq);
+       set_intr_gate(vector, interrupt[irq]);
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -1346,7 +1339,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
         * The timer IRQ doesn't have to know that behind the
         * scene we have a 8259A-master in AEOI mode ...
         */
-       irq_desc[0].chip = &ioapic_edge_type;
+       irq_desc[0].chip = &ioapic_chip;
+       set_irq_handler(0, handle_edge_irq);
 
        /*
         * Add it to the IO-APIC irq-routing table:
@@ -1481,17 +1475,12 @@ void __init print_IO_APIC(void)
                );
        }
        }
-       if (use_pci_vector())
-               printk(KERN_INFO "Using vector-based indexing\n");
        printk(KERN_DEBUG "IRQ to pin mappings:\n");
        for (i = 0; i < NR_IRQS; i++) {
                struct irq_pin_list *entry = irq_2_pin + i;
                if (entry->pin < 0)
                        continue;
-               if (use_pci_vector() && !platform_legacy_irq(i))
-                       printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-               else
-                       printk(KERN_DEBUG "IRQ%d ", i);
+               printk(KERN_DEBUG "IRQ%d ", i);
                for (;;) {
                        printk("-> %d:%d", entry->apic, entry->pin);
                        if (!entry->next)
@@ -1918,6 +1907,8 @@ static int __init timer_irq_works(void)
  */
 
 /*
+ * Startup quirk:
+ *
  * Starting up a edge-triggered IO-APIC interrupt is
  * nasty - we need to make sure that we get the edge.
  * If it is already asserted for some reason, we need
@@ -1925,8 +1916,10 @@ static int __init timer_irq_works(void)
  *
  * This is not complete - we should be able to fake
  * an edge even if it isn't on the 8259A...
+ *
+ * (We do this for level-triggered IRQs too - it cannot hurt.)
  */
-static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(unsigned int irq)
 {
        int was_pending = 0;
        unsigned long flags;
@@ -1943,47 +1936,18 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
        return was_pending;
 }
 
-/*
- * Once we have recorded IRQ_PENDING already, we can mask the
- * interrupt for real. This prevents IRQ storms from unhandled
- * devices.
- */
-static void ack_edge_ioapic_irq(unsigned int irq)
+static void ack_ioapic_irq(unsigned int irq)
 {
-       move_irq(irq);
-       if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-                                       == (IRQ_PENDING | IRQ_DISABLED))
-               mask_IO_APIC_irq(irq);
+       move_native_irq(irq);
        ack_APIC_irq();
 }
 
-/*
- * Level triggered interrupts can just be masked,
- * and shutting down and starting up the interrupt
- * is the same as enabling and disabling them -- except
- * with a startup need to return a "was pending" value.
- *
- * Level triggered interrupts are special because we
- * do not touch any IO-APIC register while handling
- * them. We ack the APIC in the end-IRQ handler, not
- * in the start-IRQ-handler. Protection against reentrance
- * from the same interrupt is still provided, both by the
- * generic IRQ layer and by the fact that an unacked local
- * APIC does not accept IRQs.
- */
-static unsigned int startup_level_ioapic_irq (unsigned int irq)
-{
-       unmask_IO_APIC_irq(irq);
-
-       return 0; /* don't check for pending */
-}
-
-static void end_level_ioapic_irq (unsigned int irq)
+static void ack_ioapic_quirk_irq(unsigned int irq)
 {
        unsigned long v;
        int i;
 
-       move_irq(irq);
+       move_native_irq(irq);
 /*
  * It appears there is an erratum which affects at least version 0x11
  * of I/O APIC (that's the 82093AA and cores integrated into various
@@ -2018,105 +1982,26 @@ static void end_level_ioapic_irq (unsigned int irq)
        }
 }
 
-#ifdef CONFIG_PCI_MSI
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       return startup_edge_ioapic_irq(irq);
-}
-
-static void ack_edge_ioapic_vector(unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       move_native_irq(vector);
-       ack_edge_ioapic_irq(irq);
-}
-
-static unsigned int startup_level_ioapic_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       return startup_level_ioapic_irq (irq);
-}
-
-static void end_level_ioapic_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       move_native_irq(vector);
-       end_level_ioapic_irq(irq);
-}
-
-static void mask_IO_APIC_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       mask_IO_APIC_irq(irq);
-}
-
-static void unmask_IO_APIC_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       unmask_IO_APIC_irq(irq);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_vector (unsigned int vector,
-                                       cpumask_t cpu_mask)
-{
-       int irq = vector_to_irq(vector);
-
-       set_native_irq_info(vector, cpu_mask);
-       set_ioapic_affinity_irq(irq, cpu_mask);
-}
-#endif
-#endif
-
-static int ioapic_retrigger(unsigned int irq)
+static int ioapic_retrigger_irq(unsigned int irq)
 {
        send_IPI_self(IO_APIC_VECTOR(irq));
 
        return 1;
 }
 
-/*
- * Level and edge triggered IO-APIC interrupts need different handling,
- * so we use two separate IRQ descriptors. Edge triggered IRQs can be
- * handled with the level-triggered descriptor, but that one has slightly
- * more overhead. Level-triggered interrupts cannot be handled with the
- * edge-triggered handler, without risking IRQ storms and other ugly
- * races.
- */
-static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-       .typename       = "IO-APIC-edge",
-       .startup        = startup_edge_ioapic,
-       .shutdown       = shutdown_edge_ioapic,
-       .enable         = enable_edge_ioapic,
-       .disable        = disable_edge_ioapic,
-       .ack            = ack_edge_ioapic,
-       .end            = end_edge_ioapic,
+static struct irq_chip ioapic_chip __read_mostly = {
+       .name           = "IO-APIC",
+       .startup        = startup_ioapic_irq,
+       .mask           = mask_IO_APIC_irq,
+       .unmask         = unmask_IO_APIC_irq,
+       .ack            = ack_ioapic_irq,
+       .eoi            = ack_ioapic_quirk_irq,
 #ifdef CONFIG_SMP
-       .set_affinity   = set_ioapic_affinity,
+       .set_affinity   = set_ioapic_affinity_irq,
 #endif
-       .retrigger      = ioapic_retrigger,
+       .retrigger      = ioapic_retrigger_irq,
 };
 
-static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-       .typename       = "IO-APIC-level",
-       .startup        = startup_level_ioapic,
-       .shutdown       = shutdown_level_ioapic,
-       .enable         = enable_level_ioapic,
-       .disable        = disable_level_ioapic,
-       .ack            = mask_and_ack_level_ioapic,
-       .end            = end_level_ioapic,
-#ifdef CONFIG_SMP
-       .set_affinity   = set_ioapic_affinity,
-#endif
-       .retrigger      = ioapic_retrigger,
-};
 
 static inline void init_IO_APIC_traps(void)
 {
@@ -2135,11 +2020,6 @@ static inline void init_IO_APIC_traps(void)
         */
        for (irq = 0; irq < NR_IRQS ; irq++) {
                int tmp = irq;
-               if (use_pci_vector()) {
-                       if (!platform_legacy_irq(tmp))
-                               if ((tmp = vector_to_irq(tmp)) == -1)
-                                       continue;
-               }
                if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
                        /*
                         * Hmm.. We don't have an entry for this,
@@ -2150,20 +2030,21 @@ static inline void init_IO_APIC_traps(void)
                                make_8259A_irq(irq);
                        else
                                /* Strange. Oh, well.. */
-                               irq_desc[irq].chip = &no_irq_type;
+                               irq_desc[irq].chip = &no_irq_chip;
                }
        }
 }
 
-static void enable_lapic_irq (unsigned int irq)
-{
-       unsigned long v;
+/*
+ * The local APIC irq-chip implementation:
+ */
 
-       v = apic_read(APIC_LVT0);
-       apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
+static void ack_apic(unsigned int irq)
+{
+       ack_APIC_irq();
 }
 
-static void disable_lapic_irq (unsigned int irq)
+static void mask_lapic_irq (unsigned int irq)
 {
        unsigned long v;
 
@@ -2171,21 +2052,19 @@ static void disable_lapic_irq (unsigned int irq)
        apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
-static void ack_lapic_irq (unsigned int irq)
+static void unmask_lapic_irq (unsigned int irq)
 {
-       ack_APIC_irq();
-}
+       unsigned long v;
 
-static void end_lapic_irq (unsigned int i) { /* nothing */ }
+       v = apic_read(APIC_LVT0);
+       apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
+}
 
-static struct hw_interrupt_type lapic_irq_type __read_mostly = {
-       .typename       = "local-APIC-edge",
-       .startup        = NULL, /* startup_irq() not used for IRQ0 */
-       .shutdown       = NULL, /* shutdown_irq() not used for IRQ0 */
-       .enable         = enable_lapic_irq,
-       .disable        = disable_lapic_irq,
-       .ack            = ack_lapic_irq,
-       .end            = end_lapic_irq
+static struct irq_chip lapic_chip __read_mostly = {
+       .name           = "local-APIC-edge",
+       .mask           = mask_lapic_irq,
+       .unmask         = unmask_lapic_irq,
+       .eoi            = ack_apic,
 };
 
 static void setup_nmi (void)
@@ -2356,7 +2235,7 @@ static inline void check_timer(void)
        printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 
        disable_8259A_irq(0);
-       irq_desc[0].chip = &lapic_irq_type;
+       set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq);
        apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);   /* Fixed mode */
        enable_8259A_irq(0);
 
@@ -2531,6 +2410,238 @@ static int __init ioapic_init_sysfs(void)
 
 device_initcall(ioapic_init_sysfs);
 
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+       /* Allocate an unused irq */
+       int irq, new, vector;
+       unsigned long flags;
+
+       irq = -ENOSPC;
+       spin_lock_irqsave(&vector_lock, flags);
+       for (new = (NR_IRQS - 1); new >= 0; new--) {
+               if (platform_legacy_irq(new))
+                       continue;
+               if (irq_vector[new] != 0)
+                       continue;
+               vector = __assign_irq_vector(new);
+               if (likely(vector > 0))
+                       irq = new;
+               break;
+       }
+       spin_unlock_irqrestore(&vector_lock, flags);
+
+       if (irq >= 0) {
+               set_intr_gate(vector, interrupt[irq]);
+               dynamic_irq_init(irq);
+       }
+       return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+       unsigned long flags;
+
+       dynamic_irq_cleanup(irq);
+
+       spin_lock_irqsave(&vector_lock, flags);
+       irq_vector[irq] = 0;
+       spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+/*
+ * MSI mesage composition
+ */
+#ifdef CONFIG_PCI_MSI
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+       int vector;
+       unsigned dest;
+
+       vector = assign_irq_vector(irq);
+       if (vector >= 0) {
+               dest = cpu_mask_to_apicid(TARGET_CPUS);
+
+               msg->address_hi = MSI_ADDR_BASE_HI;
+               msg->address_lo =
+                       MSI_ADDR_BASE_LO |
+                       ((INT_DEST_MODE == 0) ?
+                               MSI_ADDR_DEST_MODE_PHYSICAL:
+                               MSI_ADDR_DEST_MODE_LOGICAL) |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               MSI_ADDR_REDIRECTION_CPU:
+                               MSI_ADDR_REDIRECTION_LOWPRI) |
+                       MSI_ADDR_DEST_ID(dest);
+
+               msg->data =
+                       MSI_DATA_TRIGGER_EDGE |
+                       MSI_DATA_LEVEL_ASSERT |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               MSI_DATA_DELIVERY_FIXED:
+                               MSI_DATA_DELIVERY_LOWPRI) |
+                       MSI_DATA_VECTOR(vector);
+       }
+       return vector;
+}
+
+#ifdef CONFIG_SMP
+static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+       struct msi_msg msg;
+       unsigned int dest;
+       cpumask_t tmp;
+       int vector;
+
+       cpus_and(tmp, mask, cpu_online_map);
+       if (cpus_empty(tmp))
+               tmp = TARGET_CPUS;
+
+       vector = assign_irq_vector(irq);
+       if (vector < 0)
+               return;
+
+       dest = cpu_mask_to_apicid(mask);
+
+       read_msi_msg(irq, &msg);
+
+       msg.data &= ~MSI_DATA_VECTOR_MASK;
+       msg.data |= MSI_DATA_VECTOR(vector);
+       msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+       msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+       write_msi_msg(irq, &msg);
+       set_native_irq_info(irq, mask);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
+ * which implement the MSI or MSI-X Capability Structure.
+ */
+static struct irq_chip msi_chip = {
+       .name           = "PCI-MSI",
+       .unmask         = unmask_msi_irq,
+       .mask           = mask_msi_irq,
+       .ack            = ack_ioapic_irq,
+#ifdef CONFIG_SMP
+       .set_affinity   = set_msi_irq_affinity,
+#endif
+       .retrigger      = ioapic_retrigger_irq,
+};
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
+{
+       struct msi_msg msg;
+       int ret;
+       ret = msi_compose_msg(dev, irq, &msg);
+       if (ret < 0)
+               return ret;
+
+       write_msi_msg(irq, &msg);
+
+       set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+
+       return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+       return;
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+/*
+ * Hypertransport interrupt support
+ */
+#ifdef CONFIG_HT_IRQ
+
+#ifdef CONFIG_SMP
+
+static void target_ht_irq(unsigned int irq, unsigned int dest)
+{
+       u32 low, high;
+       low  = read_ht_irq_low(irq);
+       high = read_ht_irq_high(irq);
+
+       low  &= ~(HT_IRQ_LOW_DEST_ID_MASK);
+       high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+
+       low  |= HT_IRQ_LOW_DEST_ID(dest);
+       high |= HT_IRQ_HIGH_DEST_ID(dest);
+
+       write_ht_irq_low(irq, low);
+       write_ht_irq_high(irq, high);
+}
+
+static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+       unsigned int dest;
+       cpumask_t tmp;
+
+       cpus_and(tmp, mask, cpu_online_map);
+       if (cpus_empty(tmp))
+               tmp = TARGET_CPUS;
+
+       cpus_and(mask, tmp, CPU_MASK_ALL);
+
+       dest = cpu_mask_to_apicid(mask);
+
+       target_ht_irq(irq, dest);
+       set_native_irq_info(irq, mask);
+}
+#endif
+
+static struct hw_interrupt_type ht_irq_chip = {
+       .name           = "PCI-HT",
+       .mask           = mask_ht_irq,
+       .unmask         = unmask_ht_irq,
+       .ack            = ack_ioapic_irq,
+#ifdef CONFIG_SMP
+       .set_affinity   = set_ht_irq_affinity,
+#endif
+       .retrigger      = ioapic_retrigger_irq,
+};
+
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
+{
+       int vector;
+
+       vector = assign_irq_vector(irq);
+       if (vector >= 0) {
+               u32 low, high;
+               unsigned dest;
+               cpumask_t tmp;
+
+               cpus_clear(tmp);
+               cpu_set(vector >> 8, tmp);
+               dest = cpu_mask_to_apicid(tmp);
+
+               high =  HT_IRQ_HIGH_DEST_ID(dest);
+
+               low =   HT_IRQ_LOW_BASE |
+                       HT_IRQ_LOW_DEST_ID(dest) |
+                       HT_IRQ_LOW_VECTOR(vector) |
+                       ((INT_DEST_MODE == 0) ?
+                               HT_IRQ_LOW_DM_PHYSICAL :
+                               HT_IRQ_LOW_DM_LOGICAL) |
+                       HT_IRQ_LOW_RQEOI_EDGE |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               HT_IRQ_LOW_MT_FIXED :
+                               HT_IRQ_LOW_MT_ARBITRATED) |
+                       HT_IRQ_LOW_IRQ_MASKED;
+
+               write_ht_irq_low(irq, low);
+               write_ht_irq_high(irq, high);
+
+               set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+       }
+       return vector;
+}
+#endif /* CONFIG_HT_IRQ */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
@@ -2684,7 +2795,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
 
        ioapic_write_entry(ioapic, pin, entry);
        spin_lock_irqsave(&ioapic_lock, flags);
-       set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
+       set_native_irq_info(irq, TARGET_CPUS);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        return 0;
index 5fe547cd8f9fe48ab7d2e3dae930283b6baff70b..3dd2e180151bcc868c80be75875d9c054b316a26 100644 (file)
@@ -55,6 +55,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
 {      
        /* high bit used in ret_from_ code */
        int irq = ~regs->orig_eax;
+       struct irq_desc *desc = irq_desc + irq;
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
        u32 *isp;
@@ -94,7 +95,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
         * current stack (which is the irq stack already after all)
         */
        if (curctx != irqctx) {
-               int arg1, arg2, ebx;
+               int arg1, arg2, arg3, ebx;
 
                /* build the stack frame on the IRQ stack */
                isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
@@ -110,16 +111,17 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
                        (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
 
                asm volatile(
-                       "       xchgl   %%ebx,%%esp      \n"
-                       "       call    __do_IRQ         \n"
+                       "       xchgl  %%ebx,%%esp      \n"
+                       "       call   *%%edi           \n"
                        "       movl   %%ebx,%%esp      \n"
-                       : "=a" (arg1), "=d" (arg2), "=b" (ebx)
-                       :  "0" (irq),   "1" (regs),  "2" (isp)
-                       : "memory", "cc", "ecx"
+                       : "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx)
+                       :  "0" (irq),   "1" (desc),  "2" (regs),  "3" (isp),
+                          "D" (desc->handle_irq)
+                       : "memory", "cc"
                );
        } else
 #endif
-               __do_IRQ(irq, regs);
+               desc->handle_irq(irq, desc, regs);
 
        irq_exit();
 
@@ -253,7 +255,8 @@ int show_interrupts(struct seq_file *p, void *v)
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-               seq_printf(p, " %14s", irq_desc[i].chip->typename);
+               seq_printf(p, " %8s", irq_desc[i].chip->name);
+               seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
                seq_printf(p, "  %s", action->name);
 
                for (action=action->next; action; action = action->next)
index 983f95707e1169f75c761bdfd7c43e87479f7c67..445211eb2d57cdfcab06bb2a0b1f3b2b6b6ad5da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/kernel/ldt.c
+ * linux/arch/i386/kernel/ldt.c
  *
  * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
index 9d93ecf6d999d82944c017778a40a9cff5cda92c..4bb8b77cd65b257b4b54a730f5c5e3cf46595f4a 100644 (file)
@@ -648,7 +648,7 @@ static void map_cpu_to_logical_apicid(void)
 {
        int cpu = smp_processor_id();
        int apicid = logical_smp_processor_id();
-       int node = apicid_to_node(hard_smp_processor_id());
+       int node = apicid_to_node(apicid);
 
        if (!node_online(node))
                node = first_online_node;
index 828522541a88429e43b6d4ed0aa5bcae0e01af0f..5929f884d79b666c344643dbb8d5c1b59026d154 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     linux/arch/i386/mach_visws/visws_apic.c
+ *     linux/arch/i386/mach-visws/visws_apic.c
  *
  *     Copyright (C) 1999 Bent Hagemark, Ingo Molnar
  *
index 51e3739dd22700f13a28a0627163fcc6bfb94bb0..455597db84dffe2d078db1011d21653a8568650c 100644 (file)
@@ -153,8 +153,7 @@ static void __init find_max_pfn_node(int nid)
         */
        if (node_start_pfn[nid] > max_pfn)
                node_start_pfn[nid] = max_pfn;
-       if (node_start_pfn[nid] > node_end_pfn[nid])
-               BUG();
+       BUG_ON(node_start_pfn[nid] > node_end_pfn[nid]);
 }
 
 /* 
index 90089c14c23d8612673fed024e1a59ae23c98090..167416155ee41606007452bc6d14f2b845757326 100644 (file)
@@ -569,8 +569,7 @@ void __init mem_init(void)
        int bad_ppro;
 
 #ifdef CONFIG_FLATMEM
-       if (!mem_map)
-               BUG();
+       BUG_ON(!mem_map);
 #endif
        
        bad_ppro = ppro_with_ram_bug();
index 83c3645ccc43b08e085da6ba78f99b3f1f9ac0f4..b60d7e8689ede9fcb6d1ca4d0fb055d1750603f3 100644 (file)
@@ -393,7 +393,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
  * We pretend to bring them out of full D3 state, and restore the proper
  * IRQ, PCI cache line size, and BARs, otherwise the device won't function
  * properly.  In some cases, the device will generate an interrupt on
- * the wrong IRQ line, causing any devices sharing the the line it's
+ * the wrong IRQ line, causing any devices sharing the line it's
  * *supposed* to use to be disabled by the kernel's IRQ debug code.
  */
 static u16 toshiba_line_size;
index 4a8995c9c76204a1d52636884c758dc9e75bebd1..47f02af74be3735b66d0cdb1830e2fb527c1f8d0 100644 (file)
@@ -981,10 +981,6 @@ static void __init pcibios_fixup_irqs(void)
                                                        pci_name(bridge), 'A' + pin, irq);
                                }
                                if (irq >= 0) {
-                                       if (use_pci_vector() &&
-                                               !platform_legacy_irq(irq))
-                                               irq = IO_APIC_VECTOR(irq);
-
                                        printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
                                                pci_name(dev), 'A' + pin, irq);
                                        dev->irq = irq;
@@ -1169,33 +1165,3 @@ static int pirq_enable_irq(struct pci_dev *dev)
        }
        return 0;
 }
-
-int pci_vector_resources(int last, int nr_released)
-{
-       int count = nr_released;
-
-       int next = last;
-       int offset = (last % 8);
-
-       while (next < FIRST_SYSTEM_VECTOR) {
-               next += 8;
-#ifdef CONFIG_X86_64
-               if (next == IA32_SYSCALL_VECTOR)
-                       continue;
-#else
-               if (next == SYSCALL_VECTOR)
-                       continue;
-#endif
-               count++;
-               if (next >= FIRST_SYSTEM_VECTOR) {
-                       if (offset%8) {
-                               next = FIRST_DEVICE_VECTOR + offset;
-                               offset++;
-                               continue;
-                       }
-                       count--;
-               }
-       }
-
-       return count;
-}
index 31497496eb4bf2d2353b99970f84688ec8959a73..cfa099b04cda9da905309449534663de3895dc60 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_IA64_MCA_RECOVERY)       += mca_recovery.o
 obj-$(CONFIG_KPROBES)          += kprobes.o jprobes.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)  += uncached.o
 obj-$(CONFIG_AUDIT)            += audit.o
+obj-$(CONFIG_PCI_MSI)          += msi_ia64.o
 mca_recovery-y                 += mca_drv.o mca_drv_asm.o
 
 obj-$(CONFIG_IA64_ESI)         += esi.o
index e683630c8ce2930a11896360c122536fc15e2144..4d4993a47e559fe6aa27c06f45182e8478338300 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/ia64/kernel/cpufreq/processor.c
+ * arch/ia64/kernel/acpi-processor.c
  *
  * Copyright (C) 2005 Intel Corporation
  *     Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
index e5b1be51b197a5c97588df38eeb98df0b7fa1827..3390b7c5a63fab53035d6fa2986798347237f047 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ia64/kernel/entry.S
+ * arch/ia64/kernel/entry.S
  *
  * Kernel entry points.
  *
index a041367f043bb8324ea854adcb9d0c801cd41597..ab2d19c3661f0ce7b390585667646b3cb2cdccd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/ia64/kernel/irq.c
+ * linux/arch/ia64/kernel/irq_ia64.c
  *
  * Copyright (C) 1998-2001 Hewlett-Packard Co
  *     Stephane Eranian <eranian@hpl.hp.com>
@@ -30,6 +30,7 @@
 #include <linux/smp_lock.h>
 #include <linux/threads.h>
 #include <linux/bitops.h>
+#include <linux/irq.h>
 
 #include <asm/delay.h>
 #include <asm/intrinsics.h>
@@ -105,6 +106,25 @@ reserve_irq_vector (int vector)
        return test_and_set_bit(pos, ia64_vector_mask);
 }
 
+/*
+ * Dynamic irq allocate and deallocation for MSI
+ */
+int create_irq(void)
+{
+       int vector = assign_irq_vector(AUTO_ASSIGN);
+
+       if (vector >= 0)
+               dynamic_irq_init(vector);
+
+       return vector;
+}
+
+void destroy_irq(unsigned int irq)
+{
+       dynamic_irq_cleanup(irq);
+       free_irq_vector(irq);
+}
+
 #ifdef CONFIG_SMP
 #      define IS_RESCHEDULE(vec)       (vec == IA64_IPI_RESCHEDULE)
 #else
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
new file mode 100644 (file)
index 0000000..822e59a
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * MSI hooks for standard x86 apic
+ */
+
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+#include <asm/smp.h>
+
+/*
+ * Shifts for APIC-based data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT          0
+#define            MSI_DATA_VECTOR(v)          (((u8)v) << MSI_DATA_VECTOR_SHIFT)
+
+#define MSI_DATA_DELIVERY_SHIFT                8
+#define     MSI_DATA_DELIVERY_FIXED    (0 << MSI_DATA_DELIVERY_SHIFT)
+#define     MSI_DATA_DELIVERY_LOWPRI   (1 << MSI_DATA_DELIVERY_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT           14
+#define     MSI_DATA_LEVEL_DEASSERT    (0 << MSI_DATA_LEVEL_SHIFT)
+#define     MSI_DATA_LEVEL_ASSERT      (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT         15
+#define     MSI_DATA_TRIGGER_EDGE      (0 << MSI_DATA_TRIGGER_SHIFT)
+#define     MSI_DATA_TRIGGER_LEVEL     (1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for APIC-based bus address
+ */
+
+#define MSI_TARGET_CPU_SHIFT           4
+#define MSI_ADDR_HEADER                        0xfee00000
+
+#define MSI_ADDR_DESTID_MASK           0xfff0000f
+#define     MSI_ADDR_DESTID_CPU(cpu)   ((cpu) << MSI_TARGET_CPU_SHIFT)
+
+#define MSI_ADDR_DESTMODE_SHIFT                2
+#define     MSI_ADDR_DESTMODE_PHYS     (0 << MSI_ADDR_DESTMODE_SHIFT)
+#define            MSI_ADDR_DESTMODE_LOGIC     (1 << MSI_ADDR_DESTMODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT     3
+#define     MSI_ADDR_REDIRECTION_CPU   (0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define     MSI_ADDR_REDIRECTION_LOWPRI        (1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+static struct irq_chip ia64_msi_chip;
+
+#ifdef CONFIG_SMP
+static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
+{
+       struct msi_msg msg;
+       u32 addr;
+
+       read_msi_msg(irq, &msg);
+
+       addr = msg.address_lo;
+       addr &= MSI_ADDR_DESTID_MASK;
+       addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask)));
+       msg.address_lo = addr;
+
+       write_msi_msg(irq, &msg);
+       set_native_irq_info(irq, cpu_mask);
+}
+#endif /* CONFIG_SMP */
+
+int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
+{
+       struct msi_msg  msg;
+       unsigned long   dest_phys_id;
+       unsigned int    vector;
+
+       dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
+       vector = irq;
+
+       msg.address_hi = 0;
+       msg.address_lo =
+               MSI_ADDR_HEADER |
+               MSI_ADDR_DESTMODE_PHYS |
+               MSI_ADDR_REDIRECTION_CPU |
+               MSI_ADDR_DESTID_CPU(dest_phys_id);
+
+       msg.data =
+               MSI_DATA_TRIGGER_EDGE |
+               MSI_DATA_LEVEL_ASSERT |
+               MSI_DATA_DELIVERY_FIXED |
+               MSI_DATA_VECTOR(vector);
+
+       write_msi_msg(irq, &msg);
+       set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
+
+       return 0;
+}
+
+void ia64_teardown_msi_irq(unsigned int irq)
+{
+       return;         /* no-op */
+}
+
+static void ia64_ack_msi_irq(unsigned int irq)
+{
+       move_native_irq(irq);
+       ia64_eoi();
+}
+
+static int ia64_msi_retrigger_irq(unsigned int irq)
+{
+       unsigned int vector = irq;
+       ia64_resend_irq(vector);
+
+       return 1;
+}
+
+/*
+ * Generic ops used on most IA64 platforms.
+ */
+static struct irq_chip ia64_msi_chip = {
+       .name           = "PCI-MSI",
+       .mask           = mask_msi_irq,
+       .unmask         = unmask_msi_irq,
+       .ack            = ia64_ack_msi_irq,
+#ifdef CONFIG_SMP
+       .set_affinity   = ia64_set_msi_irq_affinity,
+#endif
+       .retrigger      = ia64_msi_retrigger_irq,
+};
+
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
+{
+       if (platform_setup_msi_irq)
+               return platform_setup_msi_irq(irq, pdev);
+
+       return ia64_setup_msi_irq(irq, pdev);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+       if (platform_teardown_msi_irq)
+               return platform_teardown_msi_irq(irq);
+
+       return ia64_teardown_msi_irq(irq);
+}
index 15c7c670da39e042c0173467e289be1a737efca7..b30be7c48ba8d9e79c8476181d47d15da1776fe8 100644 (file)
@@ -810,12 +810,3 @@ pcibios_prep_mwi (struct pci_dev *dev)
        }
        return rc;
 }
-
-int pci_vector_resources(int last, int nr_released)
-{
-       int count = nr_released;
-
-       count += (IA64_LAST_DEVICE_VECTOR - last);
-
-       return count;
-}
index ab9c48c88012916a28deb08d1bcf7749b1ec02af..2d78f34dd763a35f510a59388a3d59a6708be1ee 100644 (file)
@@ -19,3 +19,4 @@ xp-y                          := xp_main.o xp_nofault.o
 obj-$(CONFIG_IA64_SGI_SN_XP)   += xpc.o
 xpc-y                          := xpc_main.o xpc_channel.o xpc_partition.o
 obj-$(CONFIG_IA64_SGI_SN_XP)   += xpnet.o
+obj-$(CONFIG_PCI_MSI)          += msi_sn.o
similarity index 65%
rename from drivers/pci/msi-altix.c
rename to arch/ia64/sn/kernel/msi_sn.c
index bed4183a5e394ebf971884e37d2809c6cd8f7b7c..6ffd1f850d41bd4980b48e35a9955a14671dc6a3 100644 (file)
@@ -7,8 +7,10 @@
  */
 
 #include <linux/types.h>
+#include <linux/irq.h>
 #include <linux/pci.h>
 #include <linux/cpumask.h>
+#include <linux/msi.h>
 
 #include <asm/sn/addrs.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/pcidev.h>
 #include <asm/sn/nodepda.h>
 
-#include "msi.h"
-
 struct sn_msi_info {
        u64 pci_addr;
        struct sn_irq_info *sn_irq_info;
 };
 
-static struct sn_msi_info *sn_msi_info;
+static struct sn_msi_info sn_msi_info[NR_IRQS];
+
+static struct irq_chip sn_msi_chip;
 
-static void
-sn_msi_teardown(unsigned int vector)
+void sn_teardown_msi_irq(unsigned int irq)
 {
        nasid_t nasid;
        int widget;
@@ -36,7 +37,7 @@ sn_msi_teardown(unsigned int vector)
        struct pcibus_bussoft *bussoft;
        struct sn_pcibus_provider *provider;
 
-       sn_irq_info = sn_msi_info[vector].sn_irq_info;
+       sn_irq_info = sn_msi_info[irq].sn_irq_info;
        if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
                return;
 
@@ -45,9 +46,9 @@ sn_msi_teardown(unsigned int vector)
        provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
        (*provider->dma_unmap)(pdev,
-                              sn_msi_info[vector].pci_addr,
+                              sn_msi_info[irq].pci_addr,
                               PCI_DMA_FROMDEVICE);
-       sn_msi_info[vector].pci_addr = 0;
+       sn_msi_info[irq].pci_addr = 0;
 
        bussoft = SN_PCIDEV_BUSSOFT(pdev);
        nasid = NASID_GET(bussoft->bs_base);
@@ -56,15 +57,15 @@ sn_msi_teardown(unsigned int vector)
                        SWIN_WIDGETNUM(bussoft->bs_base);
 
        sn_intr_free(nasid, widget, sn_irq_info);
-       sn_msi_info[vector].sn_irq_info = NULL;
+       sn_msi_info[irq].sn_irq_info = NULL;
 
        return;
 }
 
-int
-sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
-            u32 *addr_hi, u32 *addr_lo, u32 *data)
+int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
 {
+       struct msi_msg msg;
+       struct msi_desc *entry;
        int widget;
        int status;
        nasid_t nasid;
@@ -73,6 +74,10 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
        struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
        struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
+       entry = get_irq_data(irq);
+       if (!entry->msi_attrib.is_64)
+               return -EINVAL;
+
        if (bussoft == NULL)
                return -EINVAL;
 
@@ -93,7 +98,7 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
        if (! sn_irq_info)
                return -ENOMEM;
 
-       status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1);
+       status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1);
        if (status) {
                kfree(sn_irq_info);
                return -ENOMEM;
@@ -119,29 +124,32 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
                return -ENOMEM;
        }
 
-       sn_msi_info[vector].sn_irq_info = sn_irq_info;
-       sn_msi_info[vector].pci_addr = bus_addr;
+       sn_msi_info[irq].sn_irq_info = sn_irq_info;
+       sn_msi_info[irq].pci_addr = bus_addr;
 
-       *addr_hi = (u32)(bus_addr >> 32);
-       *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+       msg.address_hi = (u32)(bus_addr >> 32);
+       msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
        /*
         * In the SN platform, bit 16 is a "send vector" bit which
         * must be present in order to move the vector through the system.
         */
-       *data = 0x100 + (unsigned int)vector;
+       msg.data = 0x100 + irq;
 
 #ifdef CONFIG_SMP
-       set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0);
+       set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0);
 #endif
 
+       write_msi_msg(irq, &msg);
+       set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
+
        return 0;
 }
 
-static void
-sn_msi_target(unsigned int vector, unsigned int cpu,
-             u32 *addr_hi, u32 *addr_lo)
+#ifdef CONFIG_SMP
+static void sn_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
 {
+       struct msi_msg msg;
        int slice;
        nasid_t nasid;
        u64 bus_addr;
@@ -150,8 +158,10 @@ sn_msi_target(unsigned int vector, unsigned int cpu,
        struct sn_irq_info *sn_irq_info;
        struct sn_irq_info *new_irq_info;
        struct sn_pcibus_provider *provider;
+       unsigned int cpu;
 
-       sn_irq_info = sn_msi_info[vector].sn_irq_info;
+       cpu = first_cpu(cpu_mask);
+       sn_irq_info = sn_msi_info[irq].sn_irq_info;
        if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
                return;
 
@@ -159,19 +169,20 @@ sn_msi_target(unsigned int vector, unsigned int cpu,
         * Release XIO resources for the old MSI PCI address
         */
 
+       read_msi_msg(irq, &msg);
         sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
        pdev = sn_pdev->pdi_linux_pcidev;
        provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
-       bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo);
+       bus_addr = (u64)(msg.address_hi) << 32 | (u64)(msg.address_lo);
        (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
-       sn_msi_info[vector].pci_addr = 0;
+       sn_msi_info[irq].pci_addr = 0;
 
        nasid = cpuid_to_nasid(cpu);
        slice = cpuid_to_slice(cpu);
 
        new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
-       sn_msi_info[vector].sn_irq_info = new_irq_info;
+       sn_msi_info[irq].sn_irq_info = new_irq_info;
        if (new_irq_info == NULL)
                return;
 
@@ -184,27 +195,36 @@ sn_msi_target(unsigned int vector, unsigned int cpu,
                                        sizeof(new_irq_info->irq_xtalkaddr),
                                        SN_DMA_MSI|SN_DMA_ADDR_XIO);
 
-       sn_msi_info[vector].pci_addr = bus_addr;
-       *addr_hi = (u32)(bus_addr >> 32);
-       *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
+       sn_msi_info[irq].pci_addr = bus_addr;
+       msg.address_hi = (u32)(bus_addr >> 32);
+       msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
+
+       write_msi_msg(irq, &msg);
+       set_native_irq_info(irq, cpu_mask);
 }
+#endif /* CONFIG_SMP */
 
-struct msi_ops sn_msi_ops = {
-       .setup = sn_msi_setup,
-       .teardown = sn_msi_teardown,
-#ifdef CONFIG_SMP
-       .target = sn_msi_target,
-#endif
-};
+static void sn_ack_msi_irq(unsigned int irq)
+{
+       move_native_irq(irq);
+       ia64_eoi();
+}
 
-int
-sn_msi_init(void)
+static int sn_msi_retrigger_irq(unsigned int irq)
 {
-       sn_msi_info =
-               kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL);
-       if (! sn_msi_info)
-               return -ENOMEM;
+       unsigned int vector = irq;
+       ia64_resend_irq(vector);
 
-       msi_register(&sn_msi_ops);
-       return 0;
+       return 1;
 }
+
+static struct irq_chip sn_msi_chip = {
+       .name           = "PCI-MSI",
+       .mask           = mask_msi_irq,
+       .unmask         = unmask_msi_irq,
+       .ack            = sn_ack_msi_irq,
+#ifdef CONFIG_SMP
+       .set_affinity   = sn_set_msi_irq_affinity,
+#endif
+       .retrigger      = sn_msi_retrigger_irq,
+};
index 007703c494a439b47bd82ba3898891585f38530c..c8173db0d84f628eecf9e8e41dd5699e1c8db8f0 100644 (file)
@@ -225,7 +225,7 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
        skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
 
        /*
-        * Move the data over from the the other side.
+        * Move the data over from the other side.
         */
        if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
                                                (msg->embedded_bytes != 0)) {
index 49015e32d8fcbf29dd400bcc7337c7a8dc278e0e..afcccdc6ad45db38b9b656b08cd5e5e7f3a2e95d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68k/motorola.c
+ * linux/arch/m68k/mm/motorola.c
  *
  * Routines specific to the Motorola MMU, originally from:
  * linux/arch/m68k/init.c
index 6c265222cbcdcac80cdc3cc139c6029ce594ab14..a2bc2da7f8f0ceba005c7a43a8344d59da4cb78c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68k/mm/sun3dvma.c
+ * linux/arch/m68k/sun3/sun3dvma.c
  *
  * Copyright (C) 2000 Sam Creasey
  *
index e767f2ddae72a0ca59dabb0e6e16bbfcc8ea11e7..6d920d4bdc3d4a0c47f5c83b43da1737b8d280bb 100644 (file)
@@ -161,8 +161,8 @@ config CLOCK_FREQ
          frequency, it may or may not be the same as the external clock
          crystal fitted to your board. Some processors have an internal
          PLL and can have their frequency programmed at run time, others
-         use internal dividers. In gernal the kernel won't setup a PLL
-         if it is fitted (there are some expections). This value will be
+         use internal dividers. In general the kernel won't setup a PLL
+         if it is fitted (there are some exceptions). This value will be
          specific to the exact CPU that you are using.
 
 config CLOCK_DIV
@@ -495,7 +495,7 @@ config VECTORBASE
        hex "Address of the base of system vectors"
        default "0"
        help
-         Define the address of the the system vectors. Commonly this is
+         Define the address of the system vectors. Commonly this is
          put at the start of RAM, but it doesn't have to be. On ColdFire
          platforms this address is programmed into the VBR register, thus
          actually setting the address to use.
index 9e07faa3e81d5384059d6f31c0267eb31ac18cc5..aecff532b3432cfa731e69cc525522f42e147bfc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/m68knommu/platform/68328/head-rom.S
+ * linux/arch/m68knommu/platform/68328/head-pilot.S
  * - A startup file for the MC68328
  *
  * Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
index 0dd56db9b3d0a784d50bc58e682e4b539333e8e2..e523454bda3af5588524fa283bbe165338342a73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     arch/mips/dec/call_o32.S
+ *     arch/mips/dec/prom/call_o32.S
  *
  *     O32 interface for the 64 (or N32) ABI.
  *
index 375e0991505d98d554a857b6315e7e04940be801..6f8b25cfa6f022b81b921b975b61c832f14f7f40 100644 (file)
@@ -1211,7 +1211,7 @@ static void __init build_r4000_tlb_refill_handler(void)
         * Overflow check: For the 64bit handler, we need at least one
         * free instruction slot for the wrap-around branch. In worst
         * case, if the intended insertion point is a delay slot, we
-        * need three, with the the second nop'ed and the third being
+        * need three, with the second nop'ed and the third being
         * unused.
         */
 #ifdef CONFIG_32BIT
index 8e01d0c1b76b5714dd1441298e94e4ce9a9905c2..597b89764ba10e42a664a87e51d85bb367a30f09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
+ * arch/mips/pci/fixup-vr4133.c
  *
  * The NEC CMB-VR4133 Board specific PCI fixups.
  *
index dc30d66123b6d0db892cd2ff0558cbeb2c500cb1..cbfb34221b5915d69563d9c9ff1c086605368b9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/mps/tx4938/common/irq.c
+ * linux/arch/mips/tx4938/common/irq.c
  *
  * Common tx4938 irq handler
  * Copyright (C) 2000-2001 Toshiba Corporation
index 95c1b8ec428966f4e42491ae89ebef6202819db0..192357a3b9fe0e7c7502ebc64884b4f06a99b464 100644 (file)
@@ -941,8 +941,8 @@ syscall_exit_rfi:
         * to "proper" values now (otherwise we'll wind up restoring
         * whatever was last stored in the task structure, which might
         * be inconsistent if an interrupt occured while on the gateway
-        * page) Note that we may be "trashing" values the user put in
-        * them, but we don't support the the user changing them.
+        * page). Note that we may be "trashing" values the user put in
+        * them, but we don't support the user changing them.
         */
 
        STREG   %r0,PT_SR2(%r16)
index 2587468eec430d6e2154ac13c759137db1668598..8b6910465578b02cf8d00b9c9326f302d7ef5b5e 100644 (file)
@@ -1013,7 +1013,7 @@ config CONSISTENT_START_BOOL
        depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
        help
          This option allows you to set the base virtual address
-         of the the consistent memory pool.  This pool of virtual
+         of the consistent memory pool.  This pool of virtual
          memory is used to make consistent memory allocations.
 
 config CONSISTENT_START
@@ -1024,7 +1024,7 @@ config CONSISTENT_SIZE_BOOL
        bool "Set custom consistent memory pool size"
        depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
        help
-         This option allows you to set the size of the the
+         This option allows you to set the size of the
          consistent memory pool.  This pool of virtual memory
          is used to make consistent memory allocations.
 
index c383d56bbe184b4ca549443b58a6c96dfd4d8720..003520b56303e2f4e275d436827a6a6152c8f3a4 100644 (file)
@@ -113,7 +113,7 @@ endif
 endif
 
 quiet_cmd_wrap = WRAP    $@
-      cmd_wrap =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
+      cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
 quiet_cmd_wrap_initrd = WRAP    $@
       cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
                                -i $(obj)/ramdisk.image.gz vmlinux
index bdc3977a7b062c647fb788bda68f56ecab924df7..e0dcf2b41fbe9fdddba229342f9339caaa5665d4 100644 (file)
@@ -1,4 +1,4 @@
-/* kernel/perfmon_fsl_booke.c
+/* arch/powerpc/kernel/perfmon_fsl_booke.c
  * Freescale Book-E Performance Monitor code
  *
  * Author: Andy Fleming
index e0491c3c71f18d90f616f5fea5311c17eeb50914..d8ee3aea83f890e9dc80349ecf8420bd562a7ee9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * oprofile/op_model_7450.c
+ * arch/powerpc/oprofile/op_model_7450.c
  *
  * Freescale 745x/744x oprofile support, based on fsl_booke support
  * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
index 93d63e62662f65c3439926c2d895805e501becc1..e29dede31423e0275b4aaa6818bf53b2aa831c11 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * oprofile/op_model_e500.c
+ * arch/powerpc/oprofile/op_model_fsl_booke.c
  *
  * Freescale Book-E oprofile support, based on ppc64 oprofile support
  * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
index fedecb73f7ffc84a3e9b110c4a245acd14191a89..7d5bbef084e71c986bb412be1d483ddffbf30d31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/powerppc/platforms/83xx/mpc834x_sys.h
+ * arch/powerpc/platforms/83xx/mpc834x_sys.h
  *
  * MPC834X SYS common board definitions
  *
index c0d56d2bb5a5688ef63d05daa4c2d5357955b92b..da82f4c0fdac60ed7db774b1225b3ae495a19486 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc8540_ads.h
+ * arch/powerpc/platforms/85xx/mpc8540_ads.h
  *
  * MPC8540ADS board definitions
  *
index b44db6268f3d0e4b21626001c88d28df259bd30f..83415db33378e71e22bd2f514be1071c53fee2c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc85xx.h
+ * arch/powerpc/platforms/85xx/mpc85xx.h
  *
  * MPC85xx soc definitions/function decls
  *
index 671f54ff185ac011bd091422931b6346a232e285..b251c9feb3dc244233831253a993047828c15b47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+ * arch/powerpc/platforms/85xx/mpc85xx_cds.h
  *
  * MPC85xx CDS board definitions
  *
index 0251b7c68d0e962cae5b272036343b282990c95b..6ebdae8e6f692a715cbcad22e7d4d70ab2a64944 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/ipic.c
+ * arch/powerpc/sysdev/ipic.c
  *
  * IPIC routines implementations.
  *
index 723972bb5bd9c692d157a9e79bec10cba9a80ae4..3ee03a9a98fa2bda05ca8859258901bc60279b19 100644 (file)
@@ -341,7 +341,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
                u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
                if (id == PCI_CAP_ID_HT) {
                        id = readb(devbase + pos + 3);
-                       if (id == 0x80)
+                       if (id == HT_CAPTYPE_IRQ)
                                break;
                }
        }
index fdd9e7b6624479e712031974d0029fbde452e4a6..077711e63104fc28ce53b46add1ae528a60ff996 100644 (file)
@@ -1345,7 +1345,7 @@ config CONSISTENT_START_BOOL
        depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
        help
          This option allows you to set the base virtual address
-         of the the consistent memory pool.  This pool of virtual
+         of the consistent memory pool.  This pool of virtual
          memory is used to make consistent memory allocations.
 
 config CONSISTENT_START
@@ -1356,7 +1356,7 @@ config CONSISTENT_SIZE_BOOL
        bool "Set custom consistent memory pool size"
        depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
        help
-         This option allows you to set the size of the the
+         This option allows you to set the size of the
          consistent memory pool.  This pool of virtual memory
          is used to make consistent memory allocations.
 
index 2ce7bbba72770c93b68ef1698650647f307d1a0a..9f37e1355b17d50034f42710bb98a0ae2058dc7b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/serial/mpsc/mpsc_defs.h
+ * arch/ppc/boot/include/mpsc_defs.h
  *
  * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
  * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
index cd7d0e7d986360d63eb6f1cad031c00bb9116927..66ec5f35f306c096600f22bf7834ebd433b10b15 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/xparameters.h
+ * arch/ppc/platforms/4xx/xparameters/xparameters.h
  *
  * This file includes the correct xparameters.h for the CONFIG'ed board plus
  * fixups to translate board specific XPAR values to a common set of names
index 7ddd331a7145e6d65331ece621c414a9777a7e7a..6f2d0add7de6fe0547fe4c8e088c52d66aefbd7f 100644 (file)
@@ -24,12 +24,12 @@ config MPC8540_ADS
 config MPC8548_CDS
        bool "Freescale MPC8548 CDS"
        help
-         This option enablese support for the MPC8548 CDS evaluation board.
+         This option enables support for the MPC8548 CDS evaluation board.
 
 config MPC8555_CDS
        bool "Freescale MPC8555 CDS"
        help
-         This option enablese support for the MPC8555 CDS evaluation board.
+         This option enables support for the MPC8555 CDS evaluation board.
 
 config MPC8560_ADS
        bool "Freescale MPC8560 ADS"
@@ -51,22 +51,22 @@ config STX_GP3
 config TQM8540
        bool "TQ Components TQM8540"
        help
-         This option enablese support for the TQ Components TQM8540 board.
+         This option enables support for the TQ Components TQM8540 board.
 
 config TQM8541
        bool "TQ Components TQM8541"
        help
-         This option enablese support for the TQ Components TQM8541 board.
+         This option enables support for the TQ Components TQM8541 board.
 
 config TQM8555
        bool "TQ Components TQM8555"
        help
-         This option enablese support for the TQ Components TQM8555 board.
+         This option enables support for the TQ Components TQM8555 board.
 
 config TQM8560
        bool "TQ Components TQM8560"
        help
-         This option enablese support for the TQ Components TQM8560 board.
+         This option enables support for the TQ Components TQM8560 board.
 
 endchoice
 
@@ -94,7 +94,7 @@ config MPC8560
        default y
 
 config 85xx_PCI2
-       bool "Supprt for 2nd PCI host controller"
+       bool "Support for 2nd PCI host controller"
        depends on MPC8555_CDS
        default y
 
index 5490edb2d2636e32689fb340f37586404f61ea6e..d597b6878693bbb1ce8fa87a23d806ace226c561 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/lopec_serial.h
+ * arch/ppc/platforms/lopec.h
  *
  * Definitions for Motorola LoPEC board.
  *
index d5d36c372c8e27c0b017bfcf020f3eb9d04e636d..d7b3a6afa78f86dc4209f562f9ebdedb75da34b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/82xx/pq2ads_pd.c
+ * arch/ppc/platforms/mpc8272ads_setup.c
  *
  * MPC82xx Board-specific PlatformDevice descriptions
  *
index bf388ed04d468ecdbc5e7131d49222ae39ce8beb..02293141efb5871c26f788f3a57a04cb6240cf46 100644 (file)
@@ -1,4 +1,4 @@
-/*arch/ppc/platforms/mpc885ads-setup.c
+/*arch/ppc/platforms/mpc885ads_setup.c
  *
  * Platform setup for the Freescale mpc885ads board
  *
index edd479439a4e49760b75418b908bbb641a2928df..9e2a09e636ae9813050980ab185cd32cd8a933ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/mvme5100.h
+ * arch/ppc/platforms/mvme5100.h
  *
  * Definitions for Motorola MVME5100.
  *
index 41a6dc8819115d85adc49865510c06c850d98ed7..d33ad8dc04390f33cc78d5f09dd050134f78dab2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/powerpmc250.h
+ * arch/ppc/platforms/powerpmc250.h
  *
  * Definitions for Force PowerPMC-250 board support
  *
index 015b4f52c3eb1998034bfb662baaf21d3f179ef5..4c7adcc9ae33eff352c807edfbae98544d81bab9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/prpmc750.h
+ * arch/ppc/platforms/prpmc750.h
  *
  * Definitions for Motorola PrPMC750 board support
  *
index e53ec9b42a354697a522a78075d7c772af2d6c78..26f604e05cfa70320d87439e602d2bbe8853fdc3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/prpmc800.h
+ * arch/ppc/platforms/prpmc800.h
  *
  * Definitions for Motorola PrPMC800 board support
  *
index a31ff7ee698f5eca25d3a8e087cbf3949d7a388d..f1f96f1de72a088f4f6be118ad046ee16ba8a7c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/platforms/spruce.h
+ * arch/ppc/platforms/spruce.h
  *
  * Definitions for IBM Spruce reference board support
  *
index 6835381da5fd84bb1eccd75bc85c5efa6a16cfa7..23071f97eec31ff6e61156e7aaf60915dbb5ec06 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_bigsur.c
+ * arch/sh/boards/bigsur/io.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from io_hd64465.h, which bore the message:
index 6b08c0e1c453878d56a0d81704259dcd82ac039a..d221439aafcc8e113973c94c5ba57d8d348875a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_bigsur.c
+ * linux/arch/sh/boards/bigsur/led.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from led_se.c and led.c, which bore the message:
index a70928c44753c8cb9d1df1cf50847b2e94adf5d3..2f86394b280bee02819ab6e2ea80d6319aafdc82 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_ec3104.c
+ * linux/arch/sh/boards/ec3104/io.c
  *  EC3104 companion chip support
  *
  * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
index 60ab17ad60544d79111f8ab807943875f1fa8780..2d3a5b4faf585b5dedcc201234cbf2efdfc3481d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/hp6xx/hp680/setup.c
+ * linux/arch/sh/boards/hp6xx/setup.c
  *
  * Copyright (C) 2002 Andriy Skulysh
  *
index 1fe36927f6919face11deac45acb2f7a6f8e68af..8df1591823d63b0a0299250346f72f4823e6bc00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_mpc1211.c
+ * linux/arch/sh/boards/mpc1211/led.c
  *
  * Copyright (C) 2001  Saito.K & Jeanne
  *
index 8eb5d430397257f0884400a5e6abc2ee72d915ec..01c10fa5c0589092677190289dd626120df7d20a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/board/mpc1211/setup.c
+ * linux/arch/sh/boards/mpc1211/setup.c
  *
  * Copyright (C) 2002  Saito.K & Jeanne,  Fujii.Y
  *
index 9ea1136b219b2ca9fa78cbbeda1d2127aa237fb3..51f3f6574210c712fb98adbc1d7165977c8366d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_hs7751rvoip.c
+ * linux/arch/sh/boards/renesas/hs7751rvoip/io.c
  *
  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
  * Based largely on io_se.c.
index 7e5786b581109d38a7e7dfa9c92adb6b8742f123..1c0ddee30d21f548a9a355bb778ba41611a967ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-hs7751rvoip.c
+ * linux/arch/sh/boards/renesas/hs7751rvoip/pci.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
index e14a13d12d4ad228351b90ee957304275e30bda7..a7ce66c1e4f04ceb5a39d0dbd1c95050bffe879f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_rts7751r2d.c
+ * linux/arch/sh/boards/renesas/rts7751r2d/led.c
  *
  * Copyright (C) Atom Create Engineering Co., Ltd.
  *
index cde6e5d192c417475286380ac46dcb32c7f39ca3..1b767e1a142859d50999f341f30c36f24fd4bf54 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/io.c
+ * linux/arch/sh/boards/renesas/systemh/io.c
  *
  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
  * Based largely on io_se.c.
index 8d016dae23334731a15564e2a64fad25a7665091..0ba2fe674c477057166c2d0e89428e662410b0c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/irq.c
+ * linux/arch/sh/boards/renesas/systemh/irq.c
  *
  * Copyright (C) 2000  Kazumoto Kojima
  *
index bab7d3cdc87b6f57dc1d1223843116c2c44bfb5c..936117659b74410d371ddb30046436a223448f53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/boards/systemh/setup.c
+ * linux/arch/sh/boards/renesas/systemh/setup.c
  *
  * Copyright (C) 2000  Kazumoto Kojima
  * Copyright (C) 2003  Paul Mundt
index daf7b1ee786a3f7f1d833cc4a1712cbf5d6ae6e1..d93dd831b2ade04c51dc77767171b2e223823e65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_se.c
+ * linux/arch/sh/boards/se/770x/led.c
  *
  * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
  *
index ff0355dea81b37ba235c0c53953917a44cb1a786..de4194d97c88a0225c4fe939a9980f3a6a08256f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_se.c
+ * linux/arch/sh/boards/se/7751/led.c
  *
  * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
  *
index 3ee03014dea32d9466ad0caf57e19d782524523f..203b2923fe7f8339da337a8de9573b732f096302 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-7751se.c
+ * linux/arch/sh/boards/se/7751/pci.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
index 4836b9422e2795c1fd4196661db3f24d6237426c..83419bf4c8344471e6a9e0590e700b12c3ae9fb9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/io_microdev.c
+ * linux/arch/sh/boards/superh/microdev/io.c
  *
  * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
  * Copyright (C) 2003, 2004 SuperH, Inc.
index a38f5351bd1670a4192e85f27f704357c0da64b2..36e54b47a752dda9cc67f97e8b162a4430958be4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/led_microdev.c
+ * linux/arch/sh/boards/superh/microdev/led.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
index 3b0b0f60bb3c4293af34c9a6b0f9e610b6c71af6..c1b6bc23c107f3cfc0d39941fd9cff9e2c2b9529 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/boards/dreamcast/dma-pvr2.c
+ * arch/sh/drivers/dma/dma-pvr2.c
  *
  * NEC PowerVR 2 (Dreamcast) DMA support
  *
index 6acf02b9375b8622f18e80ea0c53ed613dec4e43..230d6ec0d2398df92d56525a9cbfbbc212e03d96 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/dma-dreamcast.c
+ * arch/sh/drivers/pci/dma-dreamcast.c
  *
  * PCI DMA support for the Sega Dreamcast
  *
index c0af5f7ef4142175cfb1c863827f4b9bbc0e550e..6f53f8200dc34c5340696c19aece200b68582b1d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/fixups-dreamcast.c
+ * arch/sh/drivers/pci/fixups-dreamcast.c
  *
  * PCI fixups for the Sega Dreamcast
  *
index 5da501bd77b56cd281507a2d2c66ea323608b635..eb31be751524ee3f6b79aca1836224db1c127e67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-bigsur.c
+ * linux/arch/sh/drivers/pci/ops-bigsur.c
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  *
index 23d52791917e8abc7cc83106eab9ee394806dc22..381306cf54253e2e40f93e8954e9c1fea1abf7ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/pci/ops-dreamcast.c
+ * arch/sh/drivers/pci/ops-dreamcast.c
  *
  * PCI operations for the Sega Dreamcast
  *
index 88f44e2454244f355d3911753798c324389fecb7..b68824c8b81e72684946ac2f36628c70bd613a4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sh/kernel/pci-rts7751r2d.c
+ * linux/arch/sh/drivers/pci/ops-rts7751r2d.c
  *
  * Author:  Ian DaSilva (idasilva@mvista.com)
  *
index 0c569b20e1c1d13ceea5268d1ce15269f2d4d36a..81923079fa124ff471beb381e533e44622f17674 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/kernel/ubc.S
+ * arch/sh/kernel/cpu/ubc.S
  *
  * Set of management routines for the User Break Controller (UBC)
  *
index ee7a1b6acb83dbfdaea6a31028de1753c989cca9..aea00c53ce29f8e580e731cbbe2cb66f44a8e9e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/shmedia/boot/compressed/misc.c
+ * arch/sh64/boot/compressed/misc.c
  *
  * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
index 9079d1e94f2b53353fdf57566f47ec16865f79b1..91707c1acd70cc4aff4467a83f88164d7b49f1cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh64/kernel/alpanum.c
+ * arch/sh64/kernel/alphanum.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  *
index 53c1cabb3428c1f2487fed18eaafaccbb9a903d1..0e8a742abf8c160631449c490ef3c074e3aa93b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/lib/csum_parial.c
+ * arch/sh64/lib/c-checksum.c
  *
  * This file contains network checksum routines that are better done
  * in an architecture-specific manner due to speed..
index 8b3cc4c788708f24307179b19db175567261fa44..b4e122fd9502e7b89490c5169289e1ce70e7a0a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh64/kernel/led_cayman.c
+ * arch/sh64/mach-cayman/led.c
  *
  * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
  *
index a845b088edb4f2d487ccf1ddce9cc698f8d2242c..a750ea1fee989dbd5ee96255868ba02f5ddf9526 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/sh/oprofile/op_model_null.c
+ * arch/sh64/oprofile/op_model_null.c
  *
  * Copyright (C) 2003  Paul Mundt
  *
index c09afd96dd9c8f95d6fc8771a904e061ee716da2..01b07bb440f0744a647075db676661f8bf13efd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/sparc/sys_solaris.c
+ * linux/arch/sparc/kernel/sys_solaris.c
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
  */
index 76e85bbaea55394790be7e9971b77859af0a1c88..d75307589d74c144f39d713fea8749242e36e29f 100644 (file)
@@ -257,7 +257,7 @@ config UML_REAL_TIME_CLOCK
        UML and spend long times with UML stopped at a breakpoint.  In this
        case, when UML is restarted, it will call the timer enough times to make
        up for the time spent at the breakpoint.  This could result in a
-       noticable lag.  If this is a problem, then disable this option.
+       noticeable lag.  If this is a problem, then disable this option.
 
 endmenu
 
index f6ad832faf130dfd15714e0d54bbcb91736cce1b..c8016a98483b9ea935732f9c55307b40391b56d8 100644 (file)
@@ -102,7 +102,7 @@ linux: vmlinux
 define archhelp
   echo '* linux                - Binary kernel image (./linux) - for backward'
   echo '                  compatibility only, this creates a hard link to the'
-  echo '                  real kernel binary, the the "vmlinux" binary you'
+  echo '                  real kernel binary, the "vmlinux" binary you'
   echo '                  find in the kernel root.'
 endef
 
index 24747a413785abc575dfd16cb74f60f159ce2339..cfd9f01fd46456dab0f1a37a742a83df1876282b 100644 (file)
@@ -497,7 +497,7 @@ void close_lines(struct line *lines, int nlines)
 }
 
 /* Common setup code for both startup command line and mconsole initialization.
- * @lines contains the the array (of size @num) to modify;
+ * @lines contains the array (of size @num) to modify;
  * @init is the setup string;
  */
 
index 128faf0273644c4d01197bb76c0b5b9aaedd342c..4cd61a852fabd5c7af23beb1cab016cbff3ff393 100644 (file)
@@ -55,7 +55,7 @@
 #define PTRACE_OLDSETOPTIONS 21
 #endif
 
-/* These are before the system call, so the the system call number is RAX
+/* These are before the system call, so the system call number is RAX
  * rather than ORIG_RAX, and arg4 is R10 rather than RCX
  */
 #define REGS_SYSCALL_NR PT_INDEX(RAX)
index d991e4547dbb6ab684b6af361f575e6d142e4bd0..8bc521ca081f9a32fec0d51d12e8ef4f1044f8c3 100644 (file)
        sst.w   lp, PTO+PT_GPR(GPR_LP)[ep];                                   \
        type ## _STATE_SAVER
 /* Pop a register state pushed by PUSH_STATE, except for the stack pointer,
-   from the the stack.  */
+   from the stack.  */
 #define POP_STATE(type)                                                              \
        mov     sp, ep;                                                       \
        type ## _STATE_RESTORER;                                              \
index 0a5d8e659aa4af3a03ec080368f7ff77f68860c1..010d2265f1cfb05086017020c3533cb737cca614 100644 (file)
@@ -310,7 +310,7 @@ config K8_NUMA
        help
         Enable K8 NUMA node topology detection.  You should say Y here if
         you have a multi processor AMD K8 system. This uses an old
-        method to read the NUMA configurtion directly from the builtin
+        method to read the NUMA configuration directly from the builtin
         Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
         instead, which also takes priority if both are compiled in.   
 
index 2dd51f364ea2d62c7f779c1673a742fe839d6a71..0612a33bb896bb818001d3229c6af6652332c1df 100644 (file)
        BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
        BI(x,c) BI(x,d) BI(x,e) BI(x,f)
 
-#define BUILD_15_IRQS(x) \
-       BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
-       BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
-       BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
-       BI(x,c) BI(x,d) BI(x,e)
-
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
  * (these are usually mapped to vectors 0x20-0x2f)
  */
-BUILD_16_IRQS(0x0)
 
 /*
  * The IO-APIC gives us many more interrupt sources. Most of these 
@@ -65,17 +58,12 @@ BUILD_16_IRQS(0x0)
  *
  * (these are usually mapped into the 0x30-0xff vector range)
  */
-                  BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
+                                     BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
 BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
 BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
-BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
-
-#ifdef CONFIG_PCI_MSI
-       BUILD_15_IRQS(0xe)
-#endif
+BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
 
 #undef BUILD_16_IRQS
-#undef BUILD_15_IRQS
 #undef BI
 
 
@@ -88,29 +76,15 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
        IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
        IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
 
-#define IRQLIST_15(x) \
-       IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
-       IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
-       IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
-       IRQ(x,c), IRQ(x,d), IRQ(x,e)
-
 void (*interrupt[NR_IRQS])(void) = {
-       IRQLIST_16(0x0),
-
-                        IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
+                                         IRQLIST_16(0x2), IRQLIST_16(0x3),
        IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
        IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
-       IRQLIST_16(0xc), IRQLIST_16(0xd)
-
-#ifdef CONFIG_PCI_MSI
-       , IRQLIST_15(0xe)
-#endif
-
+       IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf)
 };
 
 #undef IRQ
 #undef IRQLIST_16
-#undef IRQLIST_14
 
 /*
  * This is the 'legacy' 8259A Programmable Interrupt Controller,
@@ -121,42 +95,15 @@ void (*interrupt[NR_IRQS])(void) = {
  * moves to arch independent land
  */
 
-DEFINE_SPINLOCK(i8259A_lock);
-
 static int i8259A_auto_eoi;
-
-static void end_8259A_irq (unsigned int irq)
-{
-       if (irq > 256) { 
-               char var;
-               printk("return %p stack %p ti %p\n", __builtin_return_address(0), &var, task_thread_info(current));
-
-               BUG(); 
-       }
-
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
-           irq_desc[irq].action)
-               enable_8259A_irq(irq);
-}
-
-#define shutdown_8259A_irq     disable_8259A_irq
-
+DEFINE_SPINLOCK(i8259A_lock);
 static void mask_and_ack_8259A(unsigned int);
 
-static unsigned int startup_8259A_irq(unsigned int irq)
-{ 
-       enable_8259A_irq(irq);
-       return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type i8259A_irq_type = {
-       .typename = "XT-PIC",
-       .startup = startup_8259A_irq,
-       .shutdown = shutdown_8259A_irq,
-       .enable = enable_8259A_irq,
-       .disable = disable_8259A_irq,
-       .ack = mask_and_ack_8259A,
-       .end = end_8259A_irq,
+static struct irq_chip i8259A_chip = {
+       .name           = "XT-PIC",
+       .mask           = disable_8259A_irq,
+       .unmask         = enable_8259A_irq,
+       .mask_ack       = mask_and_ack_8259A,
 };
 
 /*
@@ -231,7 +178,7 @@ void make_8259A_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
        io_apic_irqs &= ~(1<<irq);
-       irq_desc[irq].chip = &i8259A_irq_type;
+       set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
        enable_irq(irq);
 }
 
@@ -367,9 +314,9 @@ void init_8259A(int auto_eoi)
                 * in AEOI mode we just have to mask the interrupt
                 * when acking.
                 */
-               i8259A_irq_type.ack = disable_8259A_irq;
+               i8259A_chip.mask_ack = disable_8259A_irq;
        else
-               i8259A_irq_type.ack = mask_and_ack_8259A;
+               i8259A_chip.mask_ack = mask_and_ack_8259A;
 
        udelay(100);            /* wait for 8259A to initialize */
 
@@ -447,6 +394,26 @@ device_initcall(i8259A_init_sysfs);
  */
 
 static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
+DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
+       [0 ... FIRST_EXTERNAL_VECTOR - 1] = -1,
+       [FIRST_EXTERNAL_VECTOR + 0] = 0,
+       [FIRST_EXTERNAL_VECTOR + 1] = 1,
+       [FIRST_EXTERNAL_VECTOR + 2] = 2,
+       [FIRST_EXTERNAL_VECTOR + 3] = 3,
+       [FIRST_EXTERNAL_VECTOR + 4] = 4,
+       [FIRST_EXTERNAL_VECTOR + 5] = 5,
+       [FIRST_EXTERNAL_VECTOR + 6] = 6,
+       [FIRST_EXTERNAL_VECTOR + 7] = 7,
+       [FIRST_EXTERNAL_VECTOR + 8] = 8,
+       [FIRST_EXTERNAL_VECTOR + 9] = 9,
+       [FIRST_EXTERNAL_VECTOR + 10] = 10,
+       [FIRST_EXTERNAL_VECTOR + 11] = 11,
+       [FIRST_EXTERNAL_VECTOR + 12] = 12,
+       [FIRST_EXTERNAL_VECTOR + 13] = 13,
+       [FIRST_EXTERNAL_VECTOR + 14] = 14,
+       [FIRST_EXTERNAL_VECTOR + 15] = 15,
+       [FIRST_EXTERNAL_VECTOR + 16 ... NR_VECTORS - 1] = -1
+};
 
 void __init init_ISA_irqs (void)
 {
@@ -464,12 +431,13 @@ void __init init_ISA_irqs (void)
                        /*
                         * 16 old-style INTA-cycle interrupts:
                         */
-                       irq_desc[i].chip = &i8259A_irq_type;
+                       set_irq_chip_and_handler(i, &i8259A_chip,
+                                                handle_level_irq);
                } else {
                        /*
                         * 'high' PCI IRQs filled in on demand
                         */
-                       irq_desc[i].chip = &no_irq_type;
+                       irq_desc[i].chip = &no_irq_chip;
                }
        }
 }
@@ -543,8 +511,6 @@ void __init init_IRQ(void)
         */
        for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
                int vector = FIRST_EXTERNAL_VECTOR + i;
-               if (i >= NR_IRQS)
-                       break;
                if (vector != IA32_SYSCALL_VECTOR)
                        set_intr_gate(vector, interrupt[i]);
        }
@@ -554,7 +520,7 @@ void __init init_IRQ(void)
         * IRQ0 must be given a fixed assignment and initialized,
         * because it's used before the IO-APIC is set up.
         */
-       set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
+       __get_cpu_var(vector_irq)[FIRST_DEVICE_VECTOR] = 0;
 
        /*
         * The reschedule interrupt is a CPU-to-CPU reschedule-helper
index 0491019d4c8dc44204995cab7bf5eee7b1973c31..91728d9d34724fdcd175d83fce1c5d08290fe0dd 100644 (file)
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/pci.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/sysdev.h>
+#include <linux/msi.h>
+#include <linux/htirq.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
 #include <asm/acpi.h>
 #include <asm/dma.h>
 #include <asm/nmi.h>
+#include <asm/msidef.h>
+#include <asm/hypertransport.h>
+
+static int assign_irq_vector(int irq, cpumask_t mask);
 
 #define __apicdebuginit  __init
 
@@ -81,14 +88,6 @@ static struct irq_pin_list {
        short apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
-int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-#ifdef CONFIG_PCI_MSI
-#define vector_to_irq(vector)  \
-       (platform_legacy_irq(vector) ? vector : vector_irq[vector])
-#else
-#define vector_to_irq(vector)  (vector)
-#endif
-
 #define __DO_ACTION(R, ACTION, FINAL)                                  \
                                                                        \
 {                                                                      \
@@ -139,11 +138,35 @@ static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 }
 
 #ifdef CONFIG_SMP
+static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
+{
+       int apic, pin;
+       struct irq_pin_list *entry = irq_2_pin + irq;
+
+       BUG_ON(irq >= NR_IRQS);
+       for (;;) {
+               unsigned int reg;
+               apic = entry->apic;
+               pin = entry->pin;
+               if (pin == -1)
+                       break;
+               io_apic_write(apic, 0x11 + pin*2, dest);
+               reg = io_apic_read(apic, 0x10 + pin*2);
+               reg &= ~0x000000ff;
+               reg |= vector;
+               io_apic_modify(apic, reg);
+               if (!entry->next)
+                       break;
+               entry = irq_2_pin + entry->next;
+       }
+}
+
 static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 {
        unsigned long flags;
        unsigned int dest;
        cpumask_t tmp;
+       int vector;
 
        cpus_and(tmp, mask, cpu_online_map);
        if (cpus_empty(tmp))
@@ -151,7 +174,13 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 
        cpus_and(mask, tmp, CPU_MASK_ALL);
 
-       dest = cpu_mask_to_apicid(mask);
+       vector = assign_irq_vector(irq, mask);
+       if (vector < 0)
+               return;
+
+       cpus_clear(tmp);
+       cpu_set(vector >> 8, tmp);
+       dest = cpu_mask_to_apicid(tmp);
 
        /*
         * Only the high 8 bits are valid.
@@ -159,14 +188,12 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
        dest = SET_APIC_LOGICAL_ID(dest);
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       __DO_ACTION(1, = dest, )
-       set_irq_info(irq, mask);
+       __target_IO_APIC_irq(irq, dest, vector & 0xff);
+       set_native_irq_info(irq, mask);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 #endif
 
-static u8 gsi_2_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS-1] = 0xFF };
-
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
  * shared ISA-space IRQs, so we have to support them. We are super
@@ -492,64 +519,6 @@ static inline int irq_trigger(int idx)
        return MPBIOS_trigger(idx);
 }
 
-static int next_irq = 16;
-
-/*
- * gsi_irq_sharing -- Name overload!  "irq" can be either a legacy IRQ
- * in the range 0-15, a linux IRQ in the range 0-223, or a GSI number
- * from ACPI, which can reach 800 in large boxen.
- *
- * Compact the sparse GSI space into a sequential IRQ series and reuse
- * vectors if possible.
- */
-int gsi_irq_sharing(int gsi)
-{
-       int i, tries, vector;
-
-       BUG_ON(gsi >= NR_IRQ_VECTORS);
-
-       if (platform_legacy_irq(gsi))
-               return gsi;
-
-       if (gsi_2_irq[gsi] != 0xFF)
-               return (int)gsi_2_irq[gsi];
-
-       tries = NR_IRQS;
-  try_again:
-       vector = assign_irq_vector(gsi);
-
-       /*
-        * Sharing vectors means sharing IRQs, so scan irq_vectors for previous
-        * use of vector and if found, return that IRQ.  However, we never want
-        * to share legacy IRQs, which usually have a different trigger mode
-        * than PCI.
-        */
-       for (i = 0; i < NR_IRQS; i++)
-               if (IO_APIC_VECTOR(i) == vector)
-                       break;
-       if (platform_legacy_irq(i)) {
-               if (--tries >= 0) {
-                       IO_APIC_VECTOR(i) = 0;
-                       goto try_again;
-               }
-               panic("gsi_irq_sharing: didn't find an IRQ using vector 0x%02X for GSI %d", vector, gsi);
-       }
-       if (i < NR_IRQS) {
-               gsi_2_irq[gsi] = i;
-               printk(KERN_INFO "GSI %d sharing vector 0x%02X and IRQ %d\n",
-                               gsi, vector, i);
-               return i;
-       }
-
-       i = next_irq++;
-       BUG_ON(i >= NR_IRQS);
-       gsi_2_irq[gsi] = i;
-       IO_APIC_VECTOR(i) = vector;
-       printk(KERN_INFO "GSI %d assigned vector 0x%02X and IRQ %d\n",
-                       gsi, vector, i);
-       return i;
-}
-
 static int pin_2_irq(int idx, int apic, int pin)
 {
        int irq, i;
@@ -571,7 +540,6 @@ static int pin_2_irq(int idx, int apic, int pin)
                while (i < apic)
                        irq += nr_ioapic_registers[i++];
                irq += pin;
-               irq = gsi_irq_sharing(irq);
        }
        BUG_ON(irq >= NR_IRQS);
        return irq;
@@ -595,46 +563,83 @@ static inline int IO_APIC_irq_trigger(int irq)
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
+unsigned int irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_EXTERNAL_VECTOR, 0 };
 
-int assign_irq_vector(int irq)
+static int __assign_irq_vector(int irq, cpumask_t mask)
 {
-       static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-       unsigned long flags;
-       int vector;
-
-       BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
-
-       spin_lock_irqsave(&vector_lock, flags);
-
-       if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
-               spin_unlock_irqrestore(&vector_lock, flags);
-               return IO_APIC_VECTOR(irq);
+       /*
+        * NOTE! The local APIC isn't very good at handling
+        * multiple interrupts at the same interrupt level.
+        * As the interrupt level is determined by taking the
+        * vector number and shifting that right by 4, we
+        * want to spread these out a bit so that they don't
+        * all fall in the same interrupt level.
+        *
+        * Also, we've got to be careful not to trash gate
+        * 0x80, because int 0x80 is hm, kind of importantish. ;)
+        */
+       static struct {
+               int vector;
+               int offset;
+       } pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} };
+       int old_vector = -1;
+       int cpu;
+
+       BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
+
+       if (IO_APIC_VECTOR(irq) > 0)
+               old_vector = IO_APIC_VECTOR(irq);
+       if ((old_vector > 0) && cpu_isset(old_vector >> 8, mask)) {
+               return old_vector;
        }
+
+       for_each_cpu_mask(cpu, mask) {
+               int vector, offset;
+               vector = pos[cpu].vector;
+               offset = pos[cpu].offset;
 next:
-       current_vector += 8;
-       if (current_vector == IA32_SYSCALL_VECTOR)
-               goto next;
-
-       if (current_vector >= FIRST_SYSTEM_VECTOR) {
-               /* If we run out of vectors on large boxen, must share them. */
-               offset = (offset + 1) % 8;
-               current_vector = FIRST_DEVICE_VECTOR + offset;
+               vector += 8;
+               if (vector >= FIRST_SYSTEM_VECTOR) {
+                       /* If we run out of vectors on large boxen, must share them. */
+                       offset = (offset + 1) % 8;
+                       vector = FIRST_DEVICE_VECTOR + offset;
+               }
+               if (unlikely(pos[cpu].vector == vector))
+                       continue;
+               if (vector == IA32_SYSCALL_VECTOR)
+                       goto next;
+               if (per_cpu(vector_irq, cpu)[vector] != -1)
+                       goto next;
+               /* Found one! */
+               pos[cpu].vector = vector;
+               pos[cpu].offset = offset;
+               if (old_vector >= 0) {
+                       int old_cpu = old_vector >> 8;
+                       old_vector &= 0xff;
+                       per_cpu(vector_irq, old_cpu)[old_vector] = -1;
+               }
+               per_cpu(vector_irq, cpu)[vector] = irq;
+               vector |= cpu << 8;
+               IO_APIC_VECTOR(irq) = vector;
+               return vector;
        }
+       return -ENOSPC;
+}
 
-       vector = current_vector;
-       vector_irq[vector] = irq;
-       if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = vector;
+static int assign_irq_vector(int irq, cpumask_t mask)
+{
+       int vector;
+       unsigned long flags;
 
+       spin_lock_irqsave(&vector_lock, flags);
+       vector = __assign_irq_vector(irq, mask);
        spin_unlock_irqrestore(&vector_lock, flags);
-
        return vector;
 }
 
 extern void (*interrupt[NR_IRQS])(void);
-static struct hw_interrupt_type ioapic_level_type;
-static struct hw_interrupt_type ioapic_edge_type;
+
+static struct irq_chip ioapic_chip;
 
 #define IOAPIC_AUTO    -1
 #define IOAPIC_EDGE    0
@@ -642,16 +647,13 @@ static struct hw_interrupt_type ioapic_edge_type;
 
 static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
-       unsigned idx;
-
-       idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
-
        if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                        trigger == IOAPIC_LEVEL)
-               irq_desc[idx].chip = &ioapic_level_type;
+               set_irq_chip_and_handler(irq, &ioapic_chip,
+                                        handle_fasteoi_irq);
        else
-               irq_desc[idx].chip = &ioapic_edge_type;
-       set_intr_gate(vector, interrupt[idx]);
+               set_irq_chip_and_handler(irq, &ioapic_chip,
+                                        handle_edge_irq);
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -701,8 +703,15 @@ static void __init setup_IO_APIC_irqs(void)
                        continue;
 
                if (IO_APIC_IRQ(irq)) {
-                       vector = assign_irq_vector(irq);
-                       entry.vector = vector;
+                       cpumask_t mask;
+                       vector = assign_irq_vector(irq, TARGET_CPUS);
+                       if (vector < 0)
+                               continue;
+
+                       cpus_clear(mask);
+                       cpu_set(vector >> 8, mask);
+                       entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
+                       entry.vector = vector & 0xff;
 
                        ioapic_register_intr(irq, vector, IOAPIC_AUTO);
                        if (!apic && (irq < 16))
@@ -752,7 +761,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
         * The timer IRQ doesn't have to know that behind the
         * scene we have a 8259A-master in AEOI mode ...
         */
-       irq_desc[0].chip = &ioapic_edge_type;
+       set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq);
 
        /*
         * Add it to the IO-APIC irq-routing table:
@@ -868,17 +877,12 @@ void __apicdebuginit print_IO_APIC(void)
                );
        }
        }
-       if (use_pci_vector())
-               printk(KERN_INFO "Using vector-based indexing\n");
        printk(KERN_DEBUG "IRQ to pin mappings:\n");
        for (i = 0; i < NR_IRQS; i++) {
                struct irq_pin_list *entry = irq_2_pin + i;
                if (entry->pin < 0)
                        continue;
-               if (use_pci_vector() && !platform_legacy_irq(i))
-                       printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-               else
-                       printk(KERN_DEBUG "IRQ%d ", i);
+               printk(KERN_DEBUG "IRQ%d ", i);
                for (;;) {
                        printk("-> %d:%d", entry->apic, entry->pin);
                        if (!entry->next)
@@ -1185,7 +1189,7 @@ static int __init timer_irq_works(void)
  * an edge even if it isn't on the 8259A...
  */
 
-static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+static unsigned int startup_ioapic_irq(unsigned int irq)
 {
        int was_pending = 0;
        unsigned long flags;
@@ -1202,107 +1206,16 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
        return was_pending;
 }
 
-/*
- * Once we have recorded IRQ_PENDING already, we can mask the
- * interrupt for real. This prevents IRQ storms from unhandled
- * devices.
- */
-static void ack_edge_ioapic_irq(unsigned int irq)
-{
-       move_irq(irq);
-       if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-                                       == (IRQ_PENDING | IRQ_DISABLED))
-               mask_IO_APIC_irq(irq);
-       ack_APIC_irq();
-}
-
-/*
- * Level triggered interrupts can just be masked,
- * and shutting down and starting up the interrupt
- * is the same as enabling and disabling them -- except
- * with a startup need to return a "was pending" value.
- *
- * Level triggered interrupts are special because we
- * do not touch any IO-APIC register while handling
- * them. We ack the APIC in the end-IRQ handler, not
- * in the start-IRQ-handler. Protection against reentrance
- * from the same interrupt is still provided, both by the
- * generic IRQ layer and by the fact that an unacked local
- * APIC does not accept IRQs.
- */
-static unsigned int startup_level_ioapic_irq (unsigned int irq)
-{
-       unmask_IO_APIC_irq(irq);
-
-       return 0; /* don't check for pending */
-}
-
-static void end_level_ioapic_irq (unsigned int irq)
-{
-       move_irq(irq);
-       ack_APIC_irq();
-}
-
-#ifdef CONFIG_PCI_MSI
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       return startup_edge_ioapic_irq(irq);
-}
-
-static void ack_edge_ioapic_vector(unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       move_native_irq(vector);
-       ack_edge_ioapic_irq(irq);
-}
-
-static unsigned int startup_level_ioapic_vector (unsigned int vector)
+static int ioapic_retrigger_irq(unsigned int irq)
 {
-       int irq = vector_to_irq(vector);
+       cpumask_t mask;
+       unsigned vector;
 
-       return startup_level_ioapic_irq (irq);
-}
-
-static void end_level_ioapic_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       move_native_irq(vector);
-       end_level_ioapic_irq(irq);
-}
-
-static void mask_IO_APIC_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       mask_IO_APIC_irq(irq);
-}
+       vector = irq_vector[irq];
+       cpus_clear(mask);
+       cpu_set(vector >> 8, mask);
 
-static void unmask_IO_APIC_vector (unsigned int vector)
-{
-       int irq = vector_to_irq(vector);
-
-       unmask_IO_APIC_irq(irq);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_vector (unsigned int vector,
-                                       cpumask_t cpu_mask)
-{
-       int irq = vector_to_irq(vector);
-
-       set_native_irq_info(vector, cpu_mask);
-       set_ioapic_affinity_irq(irq, cpu_mask);
-}
-#endif // CONFIG_SMP
-#endif // CONFIG_PCI_MSI
-
-static int ioapic_retrigger(unsigned int irq)
-{
-       send_IPI_self(IO_APIC_VECTOR(irq));
+       send_IPI_mask(mask, vector & 0xff);
 
        return 1;
 }
@@ -1316,32 +1229,47 @@ static int ioapic_retrigger(unsigned int irq)
  * races.
  */
 
-static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-       .typename = "IO-APIC-edge",
-       .startup        = startup_edge_ioapic,
-       .shutdown       = shutdown_edge_ioapic,
-       .enable         = enable_edge_ioapic,
-       .disable        = disable_edge_ioapic,
-       .ack            = ack_edge_ioapic,
-       .end            = end_edge_ioapic,
-#ifdef CONFIG_SMP
-       .set_affinity = set_ioapic_affinity,
+static void ack_apic_edge(unsigned int irq)
+{
+       move_native_irq(irq);
+       ack_APIC_irq();
+}
+
+static void ack_apic_level(unsigned int irq)
+{
+       int do_unmask_irq = 0;
+
+#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+       /* If we are moving the irq we need to mask it */
+       if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+               do_unmask_irq = 1;
+               mask_IO_APIC_irq(irq);
+       }
 #endif
-       .retrigger      = ioapic_retrigger,
-};
 
-static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-       .typename = "IO-APIC-level",
-       .startup        = startup_level_ioapic,
-       .shutdown       = shutdown_level_ioapic,
-       .enable         = enable_level_ioapic,
-       .disable        = disable_level_ioapic,
-       .ack            = mask_and_ack_level_ioapic,
-       .end            = end_level_ioapic,
+       /*
+        * We must acknowledge the irq before we move it or the acknowledge will
+        * not propogate properly.
+        */
+       ack_APIC_irq();
+
+       /* Now we can move and renable the irq */
+       move_masked_irq(irq);
+       if (unlikely(do_unmask_irq))
+               unmask_IO_APIC_irq(irq);
+}
+
+static struct irq_chip ioapic_chip __read_mostly = {
+       .name           = "IO-APIC",
+       .startup        = startup_ioapic_irq,
+       .mask           = mask_IO_APIC_irq,
+       .unmask         = unmask_IO_APIC_irq,
+       .ack            = ack_apic_edge,
+       .eoi            = ack_apic_level,
 #ifdef CONFIG_SMP
-       .set_affinity = set_ioapic_affinity,
+       .set_affinity   = set_ioapic_affinity_irq,
 #endif
-       .retrigger      = ioapic_retrigger,
+       .retrigger      = ioapic_retrigger_irq,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -1361,11 +1289,6 @@ static inline void init_IO_APIC_traps(void)
         */
        for (irq = 0; irq < NR_IRQS ; irq++) {
                int tmp = irq;
-               if (use_pci_vector()) {
-                       if (!platform_legacy_irq(tmp))
-                               if ((tmp = vector_to_irq(tmp)) == -1)
-                                       continue;
-               }
                if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
                        /*
                         * Hmm.. We don't have an entry for this,
@@ -1376,7 +1299,7 @@ static inline void init_IO_APIC_traps(void)
                                make_8259A_irq(irq);
                        else
                                /* Strange. Oh, well.. */
-                               irq_desc[irq].chip = &no_irq_type;
+                               irq_desc[irq].chip = &no_irq_chip;
                }
        }
 }
@@ -1495,8 +1418,6 @@ static inline void unlock_ExtINT_logic(void)
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-int timer_uses_ioapic_pin_0;
-
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -1514,8 +1435,7 @@ static inline void check_timer(void)
         * get/set the timer IRQ vector:
         */
        disable_8259A_irq(0);
-       vector = assign_irq_vector(0);
-       set_intr_gate(vector, interrupt[0]);
+       vector = assign_irq_vector(0, TARGET_CPUS);
 
        /*
         * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1534,9 +1454,6 @@ static inline void check_timer(void)
        pin2  = ioapic_i8259.pin;
        apic2 = ioapic_i8259.apic;
 
-       if (pin1 == 0)
-               timer_uses_ioapic_pin_0 = 1;
-
        apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
                vector, apic1, pin1, apic2, pin2);
 
@@ -1740,6 +1657,253 @@ static int __init ioapic_init_sysfs(void)
 
 device_initcall(ioapic_init_sysfs);
 
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+       /* Allocate an unused irq */
+       int irq;
+       int new;
+       int vector = 0;
+       unsigned long flags;
+
+       irq = -ENOSPC;
+       spin_lock_irqsave(&vector_lock, flags);
+       for (new = (NR_IRQS - 1); new >= 0; new--) {
+               if (platform_legacy_irq(new))
+                       continue;
+               if (irq_vector[new] != 0)
+                       continue;
+               vector = __assign_irq_vector(new, TARGET_CPUS);
+               if (likely(vector > 0))
+                       irq = new;
+               break;
+       }
+       spin_unlock_irqrestore(&vector_lock, flags);
+
+       if (irq >= 0) {
+               dynamic_irq_init(irq);
+       }
+       return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+       unsigned long flags;
+
+       dynamic_irq_cleanup(irq);
+
+       spin_lock_irqsave(&vector_lock, flags);
+       irq_vector[irq] = 0;
+       spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+/*
+ * MSI mesage composition
+ */
+#ifdef CONFIG_PCI_MSI
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+       int vector;
+       unsigned dest;
+
+       vector = assign_irq_vector(irq, TARGET_CPUS);
+       if (vector >= 0) {
+               cpumask_t tmp;
+
+               cpus_clear(tmp);
+               cpu_set(vector >> 8, tmp);
+               dest = cpu_mask_to_apicid(tmp);
+
+               msg->address_hi = MSI_ADDR_BASE_HI;
+               msg->address_lo =
+                       MSI_ADDR_BASE_LO |
+                       ((INT_DEST_MODE == 0) ?
+                               MSI_ADDR_DEST_MODE_PHYSICAL:
+                               MSI_ADDR_DEST_MODE_LOGICAL) |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               MSI_ADDR_REDIRECTION_CPU:
+                               MSI_ADDR_REDIRECTION_LOWPRI) |
+                       MSI_ADDR_DEST_ID(dest);
+
+               msg->data =
+                       MSI_DATA_TRIGGER_EDGE |
+                       MSI_DATA_LEVEL_ASSERT |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               MSI_DATA_DELIVERY_FIXED:
+                               MSI_DATA_DELIVERY_LOWPRI) |
+                       MSI_DATA_VECTOR(vector);
+       }
+       return vector;
+}
+
+#ifdef CONFIG_SMP
+static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+       struct msi_msg msg;
+       unsigned int dest;
+       cpumask_t tmp;
+       int vector;
+
+       cpus_and(tmp, mask, cpu_online_map);
+       if (cpus_empty(tmp))
+               tmp = TARGET_CPUS;
+
+       cpus_and(mask, tmp, CPU_MASK_ALL);
+
+       vector = assign_irq_vector(irq, mask);
+       if (vector < 0)
+               return;
+
+       cpus_clear(tmp);
+       cpu_set(vector >> 8, tmp);
+       dest = cpu_mask_to_apicid(tmp);
+
+       read_msi_msg(irq, &msg);
+
+       msg.data &= ~MSI_DATA_VECTOR_MASK;
+       msg.data |= MSI_DATA_VECTOR(vector);
+       msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+       msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+       write_msi_msg(irq, &msg);
+       set_native_irq_info(irq, mask);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
+ * which implement the MSI or MSI-X Capability Structure.
+ */
+static struct irq_chip msi_chip = {
+       .name           = "PCI-MSI",
+       .unmask         = unmask_msi_irq,
+       .mask           = mask_msi_irq,
+       .ack            = ack_apic_edge,
+#ifdef CONFIG_SMP
+       .set_affinity   = set_msi_irq_affinity,
+#endif
+       .retrigger      = ioapic_retrigger_irq,
+};
+
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
+{
+       struct msi_msg msg;
+       int ret;
+       ret = msi_compose_msg(dev, irq, &msg);
+       if (ret < 0)
+               return ret;
+
+       write_msi_msg(irq, &msg);
+
+       set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+
+       return 0;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+       return;
+}
+
+#endif /* CONFIG_PCI_MSI */
+
+/*
+ * Hypertransport interrupt support
+ */
+#ifdef CONFIG_HT_IRQ
+
+#ifdef CONFIG_SMP
+
+static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
+{
+       u32 low, high;
+       low  = read_ht_irq_low(irq);
+       high = read_ht_irq_high(irq);
+
+       low  &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
+       high &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+
+       low  |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
+       high |= HT_IRQ_HIGH_DEST_ID(dest);
+
+       write_ht_irq_low(irq, low);
+       write_ht_irq_high(irq, high);
+}
+
+static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
+{
+       unsigned int dest;
+       cpumask_t tmp;
+       int vector;
+
+       cpus_and(tmp, mask, cpu_online_map);
+       if (cpus_empty(tmp))
+               tmp = TARGET_CPUS;
+
+       cpus_and(mask, tmp, CPU_MASK_ALL);
+
+       vector = assign_irq_vector(irq, mask);
+       if (vector < 0)
+               return;
+
+       cpus_clear(tmp);
+       cpu_set(vector >> 8, tmp);
+       dest = cpu_mask_to_apicid(tmp);
+
+       target_ht_irq(irq, dest, vector & 0xff);
+       set_native_irq_info(irq, mask);
+}
+#endif
+
+static struct hw_interrupt_type ht_irq_chip = {
+       .name           = "PCI-HT",
+       .mask           = mask_ht_irq,
+       .unmask         = unmask_ht_irq,
+       .ack            = ack_apic_edge,
+#ifdef CONFIG_SMP
+       .set_affinity   = set_ht_irq_affinity,
+#endif
+       .retrigger      = ioapic_retrigger_irq,
+};
+
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
+{
+       int vector;
+
+       vector = assign_irq_vector(irq, TARGET_CPUS);
+       if (vector >= 0) {
+               u32 low, high;
+               unsigned dest;
+               cpumask_t tmp;
+
+               cpus_clear(tmp);
+               cpu_set(vector >> 8, tmp);
+               dest = cpu_mask_to_apicid(tmp);
+
+               high =  HT_IRQ_HIGH_DEST_ID(dest);
+
+               low =   HT_IRQ_LOW_BASE |
+                       HT_IRQ_LOW_DEST_ID(dest) |
+                       HT_IRQ_LOW_VECTOR(vector) |
+                       ((INT_DEST_MODE == 0) ?
+                               HT_IRQ_LOW_DM_PHYSICAL :
+                               HT_IRQ_LOW_DM_LOGICAL) |
+                       HT_IRQ_LOW_RQEOI_EDGE |
+                       ((INT_DELIVERY_MODE != dest_LowestPrio) ?
+                               HT_IRQ_LOW_MT_FIXED :
+                               HT_IRQ_LOW_MT_ARBITRATED);
+
+               write_ht_irq_low(irq, low);
+               write_ht_irq_high(irq, high);
+
+               set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+       }
+       return vector;
+}
+#endif /* CONFIG_HT_IRQ */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
@@ -1765,6 +1929,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
 {
        struct IO_APIC_route_entry entry;
        unsigned long flags;
+       int vector;
+       cpumask_t mask;
 
        if (!IO_APIC_IRQ(irq)) {
                apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
@@ -1772,6 +1938,20 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
                return -EINVAL;
        }
 
+       /*
+        * IRQs < 16 are already in the irq_2_pin[] map
+        */
+       if (irq >= 16)
+               add_pin_to_irq(irq, ioapic, pin);
+
+
+       vector = assign_irq_vector(irq, TARGET_CPUS);
+       if (vector < 0)
+               return vector;
+
+       cpus_clear(mask);
+       cpu_set(vector >> 8, mask);
+
        /*
         * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
         * Note that we mask (disable) IRQs now -- these get enabled when the
@@ -1782,19 +1962,11 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
 
        entry.delivery_mode = INT_DELIVERY_MODE;
        entry.dest_mode = INT_DEST_MODE;
-       entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
+       entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
        entry.trigger = triggering;
        entry.polarity = polarity;
        entry.mask = 1;                                  /* Disabled (masked) */
-
-       irq = gsi_irq_sharing(irq);
-       /*
-        * IRQs < 16 are already in the irq_2_pin[] map
-        */
-       if (irq >= 16)
-               add_pin_to_irq(irq, ioapic, pin);
-
-       entry.vector = assign_irq_vector(irq);
+       entry.vector = vector & 0xff;
 
        apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
                "IRQ %d Mode:%i Active:%i)\n", ioapic, 
@@ -1809,7 +1981,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
        ioapic_write_entry(ioapic, pin, entry);
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
+       set_native_irq_info(irq, TARGET_CPUS);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        return 0;
index b3677e6ccc6ed8a2fbef0c4bdfc51041d25918be..506f27c85ca5650cc214d3635291d0ffb8ecd661 100644 (file)
@@ -74,7 +74,8 @@ int show_interrupts(struct seq_file *p, void *v)
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-               seq_printf(p, " %14s", irq_desc[i].chip->typename);
+               seq_printf(p, " %8s", irq_desc[i].chip->name);
+               seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
 
                seq_printf(p, "  %s", action->name);
                for (action=action->next; action; action = action->next)
@@ -104,7 +105,12 @@ skip:
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {      
        /* high bit used in ret_from_ code  */
-       unsigned irq = ~regs->orig_rax;
+       unsigned vector = ~regs->orig_rax;
+       unsigned irq;
+
+       exit_idle();
+       irq_enter();
+       irq = __get_cpu_var(vector_irq)[vector];
 
        if (unlikely(irq >= NR_IRQS)) {
                printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
@@ -112,12 +118,10 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
                BUG();
        }
 
-       exit_idle();
-       irq_enter();
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        stack_overflow_check(regs);
 #endif
-       __do_IRQ(irq, regs);
+       generic_handle_irq(irq, regs);
        irq_exit();
 
        return 1;
index b8d53dfa9931730a39409e2bb7c8048d6c6070cd..b147ab19fbd4d65cef63c494ed8f2ea80dddd90e 100644 (file)
@@ -790,20 +790,11 @@ void __init mp_config_acpi_legacy_irqs(void)
        }
 }
 
-#define MAX_GSI_NUM    4096
-
 int mp_register_gsi(u32 gsi, int triggering, int polarity)
 {
        int ioapic = -1;
        int ioapic_pin = 0;
        int idx, bit = 0;
-       static int pci_irq = 16;
-       /*
-        * Mapping between Global System Interrupts, which
-        * represent all possible interrupts, to the IRQs
-        * assigned to actual devices.
-        */
-       static int gsi_to_irq[MAX_GSI_NUM];
 
        if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
                return gsi;
@@ -836,42 +827,11 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
        if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
                Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-               return gsi_to_irq[gsi];
+               return gsi;
        }
 
        mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-       if (triggering == ACPI_LEVEL_SENSITIVE) {
-               /*
-                * For PCI devices assign IRQs in order, avoiding gaps
-                * due to unused I/O APIC pins.
-                */
-               int irq = gsi;
-               if (gsi < MAX_GSI_NUM) {
-                       /*
-                        * Retain the VIA chipset work-around (gsi > 15), but
-                        * avoid a problem where the 8254 timer (IRQ0) is setup
-                        * via an override (so it's not on pin 0 of the ioapic),
-                        * and at the same time, the pin 0 interrupt is a PCI
-                        * type.  The gsi > 15 test could cause these two pins
-                        * to be shared as IRQ0, and they are not shareable.
-                        * So test for this condition, and if necessary, avoid
-                        * the pin collision.
-                        */
-                       if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
-                               gsi = pci_irq++;
-                       /*
-                        * Don't assign IRQ used by ACPI SCI
-                        */
-                       if (gsi == acpi_fadt.sci_int)
-                               gsi = pci_irq++;
-                       gsi_to_irq[irq] = gsi;
-               } else {
-                       printk(KERN_ERR "GSI %u is too high\n", gsi);
-                       return gsi;
-               }
-       }
-
        io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
                triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
                polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
index 848f173db257290e0f100fdadf590cdc0a50ff77..c1e69a1f92a4bf5adbc94e9f5417487502607cf4 100644 (file)
@@ -206,7 +206,7 @@ source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
-menu "Exectuable file formats"
+menu "Executable file formats"
 
 # only elf supported
 config KCORE_ELF
@@ -241,7 +241,7 @@ menu "Xtensa initrd options"
        bool "Embed root filesystem ramdisk into the kernel"
 
 config EMBEDDED_RAMDISK_IMAGE
-       string "Filename of gziped ramdisk image"
+       string "Filename of gzipped ramdisk image"
        depends on EMBEDDED_RAMDISK
        default "ramdisk.gz"
        help
index d1683cfa19a28b6d2664130c69f08025e8b0e40c..2ea1755a085851328d63cc5153d2ccfabac4066a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/platform.c
+ * arch/xtensa/kernel/module.c
  *
  * Module support.
  *
index 1ff82268e8eacf354e5f16eae1a9ea182d3ca191..6648fa9d9192908ce7dcdc046404e151a26d9018 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/pci-dma.c
+ * arch/xtensa/kernel/pci-dma.c
  *
  * DMA coherent memory allocation.
  *
index 8709f8249d028d1109dcccfb10cfdecd89225f51..45571ccb72d63e16b169b3aa2301676d0917fc52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/pcibios.c
+ * arch/xtensa/kernel/pci.c
  *
  * PCI bios-type initialisation for PCI machines
  *
index 82684d05910a9aebd6efd61955f790f17ea7c8a5..c99ab72b41b6ee9e8d36bb5608435f45460ee74e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/setup.c
+ * arch/xtensa/kernel/setup.c
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
index d9285d4d5565bfbfa21ae1043697a2cdd5ba0f15..f49cb239e60394e13b6ebf6c512d7f7128295c85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/syscall.c
+ * arch/xtensa/kernel/syscalls.c
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
index 90c790f6123b15a623a4c81271016503884042ef..a71733ae119326fb7a99c211da375b023828b99a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/kernel/pci-auto.c
+ * arch/xtensa/lib/pci-auto.c
  *
  * PCI autoconfiguration library
  *
index 265db2693cbd3bc65157a65996712e77b17c389c..4641ef510f0e0a269dbc082e68102c70c7c0162b 100644 (file)
@@ -5,10 +5,10 @@
  *
  *  DO NOT COMBINE this function with <arch/xtensa/lib/hal/memcopy.S>.
  *  It needs to remain separate and distinct.  The hal files are part
- *  of the the Xtensa link-time HAL, and those files may differ per
+ *  of the Xtensa link-time HAL, and those files may differ per
  *  processor configuration.  Patching the kernel for another
  *  processor configuration includes replacing the hal files, and we
- *  could loose the special functionality for accessing user-space
+ *  could lose the special functionality for accessing user-space
  *  memory during such a patch.  We sacrifice a little code space here
  *  in favor to simplify code maintenance.
  *
index 7d28914d11cbc63afcf131c7ee030288803441d9..6979927382050532a4bb7d6dc47311e01ebcd18f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/mm/fault.c
+ * arch/xtensa/mm/pgtable.c
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
index d3bd3bfc3b3bd48cfa8475f76d82e31c54851d4a..0fefb866687463a562bfb6fa1ad5758d06393aec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/xtensa/mm/mmu.c
+ * arch/xtensa/mm/tlb.c
  *
  * Logic that manipulates the Xtensa MMU.  Derived from MIPS.
  *
index 3dd6b7bb5d35937e1cfa3082e3e612c9c95ca9e4..1bace29f4b6a0ae1b92dc40747ee1bdd6bde71da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/drivers/block/mfmhd.c
+ * linux/drivers/acorn/block/mfmhd.c
  *
  * Copyright (C) 1995, 1996 Russell King, Dave Alan Gilbert (gilbertd@cs.man.ac.uk)
  *
index 56c5ba874623015d499b0d022445b409c34bd904..0f9d4be7ed758814ba7c9a3e63d8620998609e04 100644 (file)
@@ -253,7 +253,7 @@ config ACPI_CUSTOM_DSDT
        depends on !STANDALONE
        default n 
        help
-         Thist option is to load a custom ACPI DSDT
+         This option is to load a custom ACPI DSDT
          If you don't know what that is, say N.
 
 config ACPI_CUSTOM_DSDT_FILE
@@ -310,7 +310,7 @@ config X86_PM_TIMER
          The Power Management Timer is available on all ACPI-capable,
          in most cases even if ACPI is unusable or blacklisted.
 
-         This timing source is not affected by powermanagement features
+         This timing source is not affected by power management features
          like aggressive processor idling, throttling, frequency and/or
          voltage scaling, unlike the commonly used Time Stamp Counter
          (TSC) timing source.
@@ -345,7 +345,7 @@ config ACPI_HOTPLUG_MEMORY
          Enabling this driver assumes that your platform hardware
          and firmware have support for hot-plugging physical memory. If
          your system does not support physically adding or ripping out 
-         memory DIMMs at some platfrom defined granularity (individually 
+         memory DIMMs at some platform defined granularity (individually 
          or as a bank) at runtime, then you need not enable this driver.
 
          If one selects "m," this driver can be loaded using the following
index 1aabc81d82f1dcc96a3dd8929f8b59d68fa6b3e3..54e1f38ce30187be1800ea581ed54589b38bcacd 100644 (file)
@@ -299,76 +299,46 @@ static const struct ata_port_info ahci_port_info[] = {
 
 static const struct pci_device_id ahci_pci_tbl[] = {
        /* Intel */
-       { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH6 */
-       { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH6M */
-       { PCI_VENDOR_ID_INTEL, 0x27c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH7 */
-       { PCI_VENDOR_ID_INTEL, 0x27c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH7M */
-       { PCI_VENDOR_ID_INTEL, 0x27c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH7R */
-       { PCI_VENDOR_ID_AL, 0x5288, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ULi M5288 */
-       { PCI_VENDOR_ID_INTEL, 0x2681, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ESB2 */
-       { PCI_VENDOR_ID_INTEL, 0x2682, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ESB2 */
-       { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ESB2 */
-       { PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH7-M DH */
-       { PCI_VENDOR_ID_INTEL, 0x2821, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH8 */
-       { PCI_VENDOR_ID_INTEL, 0x2822, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH8 */
-       { PCI_VENDOR_ID_INTEL, 0x2824, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH8 */
-       { PCI_VENDOR_ID_INTEL, 0x2829, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH8M */
-       { PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ICH8M */
+       { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
+       { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
+       { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
+       { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
+       { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
+       { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */
+       { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
+       { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
+       { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
+       { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
+       { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
+       { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
+       { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
 
        /* JMicron */
-       { 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* JMicron JMB360 */
-       { 0x197b, 0x2361, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* JMicron JMB361 */
-       { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* JMicron JMB363 */
-       { 0x197b, 0x2365, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* JMicron JMB365 */
-       { 0x197b, 0x2366, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* JMicron JMB366 */
+       { PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */
+       { PCI_VDEVICE(JMICRON, 0x2361), board_ahci }, /* JMicron JMB361 */
+       { PCI_VDEVICE(JMICRON, 0x2363), board_ahci }, /* JMicron JMB363 */
+       { PCI_VDEVICE(JMICRON, 0x2365), board_ahci }, /* JMicron JMB365 */
+       { PCI_VDEVICE(JMICRON, 0x2366), board_ahci }, /* JMicron JMB366 */
 
        /* ATI */
-       { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ATI SB600 non-raid */
-       { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* ATI SB600 raid */
+       { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
+       { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
 
        /* VIA */
-       { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci_vt8251 }, /* VIA VT8251 */
+       { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
 
        /* NVIDIA */
-       { PCI_VENDOR_ID_NVIDIA, 0x044c, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci },         /* MCP65 */
-       { PCI_VENDOR_ID_NVIDIA, 0x044d, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci },         /* MCP65 */
-       { PCI_VENDOR_ID_NVIDIA, 0x044e, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci },         /* MCP65 */
-       { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci },         /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci },            /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci },            /* MCP65 */
 
        /* SiS */
-       { PCI_VENDOR_ID_SI, 0x1184, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* SiS 966 */
-       { PCI_VENDOR_ID_SI, 0x1185, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* SiS 966 */
-       { PCI_VENDOR_ID_SI, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_ahci }, /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
+       { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
+       { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
 
        { }     /* terminate list */
 };
index b4abd6850367d219e2cb1d59218bf7773b147879..dce65651d8586ffb67c4bf4dcc3efc38940cc8b0 100644 (file)
@@ -2340,7 +2340,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
 
        if (status & ATA_BUSY)
                ata_port_printk(ap, KERN_WARNING,
-                               "port is slow to respond, please be patient\n");
+                               "port is slow to respond, please be patient "
+                               "(Status 0x%x)\n", status);
 
        timeout = timer_start + tmout;
        while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
@@ -2350,7 +2351,8 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
 
        if (status & ATA_BUSY) {
                ata_port_printk(ap, KERN_ERR, "port failed to respond "
-                               "(%lu secs)\n", tmout / HZ);
+                               "(%lu secs, Status 0x%x)\n",
+                               tmout / HZ, status);
                return 1;
        }
 
@@ -5478,11 +5480,10 @@ int ata_device_add(const struct ata_probe_ent *ent)
                int irq_line = ent->irq;
 
                ap = ata_port_add(ent, host, i);
+               host->ports[i] = ap;
                if (!ap)
                        goto err_out;
 
-               host->ports[i] = ap;
-
                /* dummy? */
                if (ent->dummy_port_mask & (1 << i)) {
                        ata_port_printk(ap, KERN_INFO, "DUMMY\n");
@@ -5740,7 +5741,7 @@ void ata_host_remove(struct ata_host *host)
 
 /**
  *     ata_scsi_release - SCSI layer callback hook for host unload
- *     @host: libata host to be unloaded
+ *     @shost: libata host to be unloaded
  *
  *     Performs all duties necessary to shut down a libata port...
  *     Kill port kthread, disable port, and release resources.
@@ -5786,6 +5787,7 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
        probe_ent->mwdma_mask = port->mwdma_mask;
        probe_ent->udma_mask = port->udma_mask;
        probe_ent->port_ops = port->port_ops;
+       probe_ent->private_data = port->private_data;
 
        return probe_ent;
 }
index 3986ec8741b4157ba46e1415f0487cb05b4fb8d0..b0d0cc41f3e8332041195a71e97c98405a04650c 100644 (file)
@@ -889,6 +889,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
 {
        struct ata_port *ap = ata_shost_to_port(sdev->host);
        struct ata_device *dev;
+       unsigned long flags;
        int max_depth;
 
        if (queue_depth < 1)
@@ -904,6 +905,14 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
                queue_depth = max_depth;
 
        scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
+
+       spin_lock_irqsave(ap->lock, flags);
+       if (queue_depth > 1)
+               dev->flags &= ~ATA_DFLAG_NCQ_OFF;
+       else
+               dev->flags |= ATA_DFLAG_NCQ_OFF;
+       spin_unlock_irqrestore(ap->lock, flags);
+
        return queue_depth;
 }
 
@@ -1293,7 +1302,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                 */
                goto nothing_to_do;
 
-       if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
+       if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
+                          ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
                /* yay, NCQ */
                if (!lba_48_ok(block, n_block))
                        goto out_of_range;
@@ -3174,7 +3184,7 @@ void ata_scsi_dev_rescan(void *data)
 
 /**
  *     ata_sas_port_alloc - Allocate port for a SAS attached SATA device
- *     @pdev: PCI device that the scsi device is attached to
+ *     @host: ATA host container for all SAS ports
  *     @port_info: Information from low-level host driver
  *     @shost: SCSI host that the scsi device is attached to
  *
index 08b3a407473ea47688beb7d91dca4f8d2543bbe0..06daaa3736a2cbcd35efde2e377d0ad90cfc5d98 100644 (file)
@@ -828,7 +828,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
 
        probe_ent->irq = pdev->irq;
        probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->private_data = port[0]->private_data;
 
        if (ports & ATA_PORT_PRIMARY) {
                probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
@@ -878,7 +877,6 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
                return NULL;
 
        probe_ent->n_ports = 2;
-       probe_ent->private_data = port[0]->private_data;
 
        if (port_mask & ATA_PORT_PRIMARY) {
                probe_ent->irq = ATA_PRIMARY_IRQ;
@@ -908,6 +906,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
                                probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
                }
                ata_std_ports(&probe_ent->port[1]);
+
+               /* FIXME: could be pointing to stack area; must copy */
                probe_ent->pinfo2 = port[1];
        } else
                probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
@@ -946,35 +946,21 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 {
        struct ata_probe_ent *probe_ent = NULL;
        struct ata_port_info *port[2];
-       u8 tmp8, mask;
+       u8 mask;
        unsigned int legacy_mode = 0;
        int disable_dev_on_err = 1;
        int rc;
 
        DPRINTK("ENTER\n");
 
+       BUG_ON(n_ports < 1 || n_ports > 2);
+
        port[0] = port_info[0];
        if (n_ports > 1)
                port[1] = port_info[1];
        else
                port[1] = port[0];
 
-       if ((port[0]->flags & ATA_FLAG_NO_LEGACY) == 0
-           && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-               /* TODO: What if one channel is in native mode ... */
-               pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
-               mask = (1 << 2) | (1 << 0);
-               if ((tmp8 & mask) != mask)
-                       legacy_mode = (1 << 3);
-       }
-
-       /* FIXME... */
-       if ((!legacy_mode) && (n_ports > 2)) {
-               printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
-               n_ports = 2;
-               /* For now */
-       }
-
        /* FIXME: Really for ATA it isn't safe because the device may be
           multi-purpose and we want to leave it alone if it was already
           enabled. Secondly for shared use as Arjan says we want refcounting
@@ -987,6 +973,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
        if (rc)
                return rc;
 
+       if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+               u8 tmp8;
+
+               /* TODO: What if one channel is in native mode ... */
+               pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
+               mask = (1 << 2) | (1 << 0);
+               if ((tmp8 & mask) != mask)
+                       legacy_mode = (1 << 3);
+       }
+
        rc = pci_request_regions(pdev, DRV_NAME);
        if (rc) {
                disable_dev_on_err = 0;
@@ -1039,7 +1035,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out_regions;
        }
 
-       /* FIXME: If we get no DMA mask we should fall back to PIO */
+       /* TODO: If we get no DMA mask we should fall back to PIO */
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                goto err_out_regions;
@@ -1062,13 +1058,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 
        pci_set_master(pdev);
 
-       /* FIXME: check ata_device_add return */
-       ata_device_add(probe_ent);
+       if (!ata_device_add(probe_ent)) {
+               rc = -ENODEV;
+               goto err_out_ent;
+       }
 
        kfree(probe_ent);
 
        return 0;
 
+err_out_ent:
+       kfree(probe_ent);
 err_out_regions:
        if (legacy_mode & ATA_PORT_PRIMARY)
                release_region(ATA_PRIMARY_CMD, 8);
index 87af3b5861ab0276340822e5eb28f5c15ba76060..1d695df5860a3ac44fc77476847d88f50927d7fb 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME "pata_ali"
-#define DRV_VERSION "0.6.5"
+#define DRV_VERSION "0.6.6"
 
 /*
  *     Cable special cases
@@ -630,7 +630,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                pci_read_config_byte(pdev, 0x53, &tmp);
                if (rev <= 0x20)
                        tmp &= ~0x02;
-               if (rev == 0xc7)
+               if (rev >= 0xc7)
                        tmp |= 0x03;
                else
                        tmp |= 0x01;    /* CD_ROM enable for DMA */
@@ -644,10 +644,11 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id ali[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228), },
-       { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229), },
-       { 0, },
+static const struct pci_device_id ali[] = {
+       { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
+       { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), },
+
+       { },
 };
 
 static struct pci_driver ali_pci_driver = {
index 599ee266722ccffe6492650263342ee838eedd16..29234c897118eb5d84cfaf08b18cd8560d524390 100644 (file)
@@ -662,27 +662,28 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id amd[] = {
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_COBRA_7401,           PCI_ANY_ID, PCI_ANY_ID, 0, 0,  0 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_VIPER_7409,           PCI_ANY_ID, PCI_ANY_ID, 0, 0,  1 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_VIPER_7411,           PCI_ANY_ID, PCI_ANY_ID, 0, 0,  3 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_OPUS_7441,            PCI_ANY_ID, PCI_ANY_ID, 0, 0,  4 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_8111_IDE,             PCI_ANY_ID, PCI_ANY_ID, 0, 0,  5 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,        PCI_ANY_ID, PCI_ANY_ID, 0, 0,  7 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,       PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,      PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,       PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,      PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_CS5536_IDE,           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
-       { 0, },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_COBRA_7401),          0 },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_VIPER_7409),          1 },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_VIPER_7411),          3 },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_OPUS_7441),           4 },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_8111_IDE),            5 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_IDE),       7 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE),      8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE),     8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE),      8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE),     8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE), 8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE), 8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 },
+       { PCI_VDEVICE(NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 },
+       { PCI_VDEVICE(AMD,      PCI_DEVICE_ID_AMD_CS5536_IDE),          9 },
+
+       { },
 };
 
 static struct pci_driver amd_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = amd,
        .probe          = amd_init_one,
        .remove         = ata_pci_remove_one
@@ -698,7 +699,6 @@ static void __exit amd_exit(void)
        pci_unregister_driver(&amd_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for AMD PATA IDE");
 MODULE_LICENSE("GPL");
index c4ccb75a4f1d69a2bebba5eb2e9e08640af986d0..690828eb5226e8d48a3c7f59cb39ab48ba4ae968 100644 (file)
@@ -426,7 +426,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops       = &artop6260_ops,
        };
        struct ata_port_info *port_info[2];
-       struct ata_port_info *info;
+       struct ata_port_info *info = NULL;
        int ports = 2;
 
        if (!printed_version++)
@@ -470,16 +470,20 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
 
        }
+
+       BUG_ON(info == NULL);
+
        port_info[0] = port_info[1] = info;
        return ata_pci_init_one(pdev, port_info, ports);
 }
 
 static const struct pci_device_id artop_pci_tbl[] = {
-       { 0x1191, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { 0x1191, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-       { 0x1191, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-       { 0x1191, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-       { 0x1191, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+       { PCI_VDEVICE(ARTOP, 0x0005), 0 },
+       { PCI_VDEVICE(ARTOP, 0x0006), 1 },
+       { PCI_VDEVICE(ARTOP, 0x0007), 1 },
+       { PCI_VDEVICE(ARTOP, 0x0008), 2 },
+       { PCI_VDEVICE(ARTOP, 0x0009), 2 },
+
        { }     /* terminate list */
 };
 
@@ -500,7 +504,6 @@ static void __exit artop_exit(void)
        pci_unregister_driver(&artop_pci_driver);
 }
 
-
 module_init(artop_init);
 module_exit(artop_exit);
 
index 6c2269b6bd3c0d74cc079548681ccbf15935f067..1ce28d2125f400f1cc7579ce83fb87c1f0d0b1e3 100644 (file)
@@ -267,12 +267,13 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id atiixp[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
-       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
-       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
-       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
-       { 0, },
+static const struct pci_device_id atiixp[] = {
+       { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
+       { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
+       { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
+       { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
+
+       { },
 };
 
 static struct pci_driver atiixp_pci_driver = {
@@ -293,7 +294,6 @@ static void __exit atiixp_exit(void)
        pci_unregister_driver(&atiixp_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400");
 MODULE_LICENSE("GPL");
index e92b0ef43ec55a34e7d390d001bdbb413d8b8648..b9bbd1d454bf25229212e584ab0bab735991b09d 100644 (file)
@@ -468,16 +468,17 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id cmd64x[] = {
-       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
-       { 0, },
+static const struct pci_device_id cmd64x[] = {
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 4 },
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 5 },
+
+       { },
 };
 
 static struct pci_driver cmd64x_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = cmd64x,
        .probe          = cmd64x_init_one,
        .remove         = ata_pci_remove_one
@@ -488,13 +489,11 @@ static int __init cmd64x_init(void)
        return pci_register_driver(&cmd64x_pci_driver);
 }
 
-
 static void __exit cmd64x_exit(void)
 {
        pci_unregister_driver(&cmd64x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers");
 MODULE_LICENSE("GPL");
index a6c6cebd0dae53e38bc9fd24cadba220ee5b921e..2cd3c0ff76df313cfa619aa62d407e4bf33e03ee 100644 (file)
@@ -299,10 +299,11 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
 /* For now keep DMA off. We can set it for all but A rev CS5510 once the
    core ATA code can handle it */
 
-static struct pci_device_id pata_cs5520[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
-       { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
-       { 0, },
+static const struct pci_device_id pata_cs5520[] = {
+       { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
+       { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
+
+       { },
 };
 
 static struct pci_driver cs5520_pci_driver = {
@@ -312,7 +313,6 @@ static struct pci_driver cs5520_pci_driver = {
        .remove         = cs5520_remove_one
 };
 
-
 static int __init cs5520_init(void)
 {
        return pci_register_driver(&cs5520_pci_driver);
index 7bba4d954e9c00ae43f6f8af3b94358fd2661348..a07cc81ef7916dfdc8814ec298ed187b35403c71 100644 (file)
@@ -353,13 +353,14 @@ fail_put:
        return -ENODEV;
 }
 
-static struct pci_device_id cs5530[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
-       { 0, },
+static const struct pci_device_id cs5530[] = {
+       { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
+
+       { },
 };
 
 static struct pci_driver cs5530_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = cs5530,
        .probe          = cs5530_init_one,
        .remove         = ata_pci_remove_one
@@ -370,13 +371,11 @@ static int __init cs5530_init(void)
        return pci_register_driver(&cs5530_pci_driver);
 }
 
-
 static void __exit cs5530_exit(void)
 {
        pci_unregister_driver(&cs5530_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530");
 MODULE_LICENSE("GPL");
index d64fcdceaf01e917283c6c8f07effd20a4ad36bf..f8def3f9c618aa51592a7a837e47e4b52605341c 100644 (file)
@@ -257,9 +257,10 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, ports, 1);
 }
 
-static struct pci_device_id cs5535[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), },
-       { 0, },
+static const struct pci_device_id cs5535[] = {
+       { PCI_VDEVICE(NS, 0x002D), },
+
+       { },
 };
 
 static struct pci_driver cs5535_pci_driver = {
@@ -274,13 +275,11 @@ static int __init cs5535_init(void)
        return pci_register_driver(&cs5535_pci_driver);
 }
 
-
 static void __exit cs5535_exit(void)
 {
        pci_unregister_driver(&cs5535_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch");
 MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530");
 MODULE_LICENSE("GPL");
index dfa5ac5390481dcb58e8ef60b19de6cfb4955fdd..247b43608b14e0fb8fc26447a54fd1d2f57cfdea 100644 (file)
@@ -184,8 +184,8 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
        };
        static struct ata_port_info *port_info[1] = { &info };
 
-       /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the
-          moment we don't handle the secondary. FIXME */
+       /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2.
+          For the moment we don't handle the secondary. FIXME */
 
        if (PCI_FUNC(pdev->devfn) != 1)
                return -ENODEV;
@@ -193,13 +193,14 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
        return ata_pci_init_one(pdev, port_info, 1);
 }
 
-static struct pci_device_id cy82c693[] = {
-       { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { 0, },
+static const struct pci_device_id cy82c693[] = {
+       { PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), },
+
+       { },
 };
 
 static struct pci_driver cy82c693_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = cy82c693,
        .probe          = cy82c693_init_one,
        .remove         = ata_pci_remove_one
index 95cd1ca181f5b9332cadc9c883f9cffe91ed08ec..ef18c60fe14027802f3bfc2ff4e8c7496320fda7 100644 (file)
@@ -305,7 +305,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 }
 
 static const struct pci_device_id efar_pci_tbl[] = {
-       { 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VDEVICE(EFAR, 0x9130), },
+
        { }     /* terminate list */
 };
 
@@ -326,7 +327,6 @@ static void __exit efar_exit(void)
        pci_unregister_driver(&efar_pci_driver);
 }
 
-
 module_init(efar_init);
 module_exit(efar_exit);
 
index 8c757438f350329e47e045b88a930587e9267520..6d3e4c0f15febf1c6a9afd125cedca6b0d5a932c 100644 (file)
@@ -444,13 +444,14 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt36x[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-       { 0, },
+static const struct pci_device_id hpt36x[] = {
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+
+       { },
 };
 
 static struct pci_driver hpt36x_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = hpt36x,
        .probe          = hpt36x_init_one,
        .remove         = ata_pci_remove_one
index 10318c0012ef84a9c957f96229ab933d91c18c71..7350443948c177e337583966d6eff3c460db7eca 100644 (file)
@@ -1219,17 +1219,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt37x[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), },
-       { 0, },
+static const struct pci_device_id hpt37x[] = {
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
+
+       { },
 };
 
 static struct pci_driver hpt37x_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = hpt37x,
        .probe          = hpt37x_init_one,
        .remove         = ata_pci_remove_one
@@ -1240,13 +1241,11 @@ static int __init hpt37x_init(void)
        return pci_register_driver(&hpt37x_pci_driver);
 }
 
-
 static void __exit hpt37x_exit(void)
 {
        pci_unregister_driver(&hpt37x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
 MODULE_LICENSE("GPL");
index 5c5d4f6ab901e699c55cf3e327104ea6804b434f..58cfb2bc8098ba1e3e542a7354d07c7952da4be4 100644 (file)
@@ -560,16 +560,17 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt3x2n[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), },
-       { 0, },
+static const struct pci_device_id hpt3x2n[] = {
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
+
+       { },
 };
 
 static struct pci_driver hpt3x2n_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = hpt3x2n,
        .probe          = hpt3x2n_init_one,
        .remove         = ata_pci_remove_one
@@ -580,13 +581,11 @@ static int __init hpt3x2n_init(void)
        return pci_register_driver(&hpt3x2n_pci_driver);
 }
 
-
 static void __exit hpt3x2n_exit(void)
 {
        pci_unregister_driver(&hpt3x2n_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x");
 MODULE_LICENSE("GPL");
index 1f084ab1ccc6a65d6081c056ef7565b994e4895e..3334d72e251bf675b4d326c3eacbba76db998bb4 100644 (file)
@@ -192,13 +192,14 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id hpt3x3[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), },
-       { 0, },
+static const struct pci_device_id hpt3x3[] = {
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
+
+       { },
 };
 
 static struct pci_driver hpt3x3_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = hpt3x3,
        .probe          = hpt3x3_init_one,
        .remove         = ata_pci_remove_one
index 82a46ff4000095d378c3bab18f7e926a60b2947b..18ff3e59a89bad0f4db82192660009ad25bbc52c 100644 (file)
@@ -808,14 +808,15 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        return ata_pci_init_one(pdev, port_info, 2);
 }
 
-static struct pci_device_id it821x[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211), },
-       { PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212), },
-       { 0, },
+static const struct pci_device_id it821x[] = {
+       { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
+       { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
+
+       { },
 };
 
 static struct pci_driver it821x_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = it821x,
        .probe          = it821x_init_one,
        .remove         = ata_pci_remove_one
@@ -826,13 +827,11 @@ static int __init it821x_init(void)
        return pci_register_driver(&it821x_pci_driver);
 }
 
-
 static void __exit it821x_exit(void)
 {
        pci_unregister_driver(&it821x_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for the IT8211/IT8212 IDE RAID controller");
 MODULE_LICENSE("GPL");
index be3a866b111faa3d23a8ea7ca1285d22dd72828d..52a2bdf3c38de3109877679c1ef25a48de65873e 100644 (file)
@@ -229,11 +229,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 }
 
 static const struct pci_device_id jmicron_pci_tbl[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
-       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
-       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365},
-       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366},
-       { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368},
+       { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
+       { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
+       { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365},
+       { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366},
+       { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368},
+
        { }     /* terminate list */
 };
 
index 3c65393c1f01abfa9e7ab93e81c18323e1f6eb63..9dfe3e9abea31bf21d2d63136d54247d4bee52a5 100644 (file)
@@ -274,11 +274,10 @@ static void __devexit mpiix_remove_one(struct pci_dev *pdev)
        dev_set_drvdata(dev, NULL);
 }
 
-
-
 static const struct pci_device_id mpiix[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
-       { 0, },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
+
+       { },
 };
 
 static struct pci_driver mpiix_pci_driver = {
@@ -293,13 +292,11 @@ static int __init mpiix_init(void)
        return pci_register_driver(&mpiix_pci_driver);
 }
 
-
 static void __exit mpiix_exit(void)
 {
        pci_unregister_driver(&mpiix_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Intel MPIIX");
 MODULE_LICENSE("GPL");
index 76eb9c90bee1f3759b8194aabebfe23b95b65e09..f5672de99c22d3012bb419e5956e410db3f83f74 100644 (file)
@@ -142,7 +142,8 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 }
 
 static const struct pci_device_id netcell_pci_tbl[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_NETCELL, PCI_DEVICE_ID_REVOLUTION), },
+       { PCI_VDEVICE(NETCELL, PCI_DEVICE_ID_REVOLUTION), },
+
        { }     /* terminate list */
 };
 
index 2005a95f48f6524be0e54206e7edbc97b0a51c7e..2a3dbeed89b469d25bd7c7f6ab8849721d76c37a 100644 (file)
@@ -200,12 +200,13 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id ns87410[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), },
-       { 0, },
+       { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87410), },
+
+       { },
 };
 
 static struct pci_driver ns87410_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = ns87410,
        .probe          = ns87410_init_one,
        .remove         = ata_pci_remove_one
@@ -216,13 +217,11 @@ static int __init ns87410_init(void)
        return pci_register_driver(&ns87410_pci_driver);
 }
 
-
 static void __exit ns87410_exit(void)
 {
        pci_unregister_driver(&ns87410_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Nat Semi 87410");
 MODULE_LICENSE("GPL");
index 31a285ca88dceb0e0292a17859b54ed279647424..fc947dfecd73e97c2c22994e3a747d7c3f607723 100644 (file)
@@ -303,7 +303,8 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 }
 
 static const struct pci_device_id oldpiix_pci_tbl[] = {
-       { PCI_DEVICE(0x8086, 0x1230), },
+       { PCI_VDEVICE(INTEL, 0x1230), },
+
        { }     /* terminate list */
 };
 
@@ -324,7 +325,6 @@ static void __exit oldpiix_exit(void)
        pci_unregister_driver(&oldpiix_pci_driver);
 }
 
-
 module_init(oldpiix_init);
 module_exit(oldpiix_exit);
 
index 57fe21f3a97549c1617f71ba7dffb424a7229f24..a7320ba15575490e85e1905b26b4669e4c18c173 100644 (file)
@@ -256,13 +256,14 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id opti[] = {
-       { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-       { 0, },
+       { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 },
+       { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 },
+
+       { },
 };
 
 static struct pci_driver opti_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = opti,
        .probe          = opti_init_one,
        .remove         = ata_pci_remove_one
@@ -273,7 +274,6 @@ static int __init opti_init(void)
        return pci_register_driver(&opti_pci_driver);
 }
 
-
 static void __exit opti_exit(void)
 {
        pci_unregister_driver(&opti_pci_driver);
index 7296a20cd107310314448b21b4e5e5f445e65a18..c6906b4215de266d595e175672554d81d2c870a2 100644 (file)
@@ -512,12 +512,13 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id optidma[] = {
-       { PCI_DEVICE(0x1045, 0xD568), },        /* Opti 82C700 */
-       { 0, },
+       { PCI_VDEVICE(OPTI, 0xD568), },         /* Opti 82C700 */
+
+       { },
 };
 
 static struct pci_driver optidma_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = optidma,
        .probe          = optidma_init_one,
        .remove         = ata_pci_remove_one
@@ -528,13 +529,11 @@ static int __init optidma_init(void)
        return pci_register_driver(&optidma_pci_driver);
 }
 
-
 static void __exit optidma_exit(void)
 {
        pci_unregister_driver(&optidma_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus");
 MODULE_LICENSE("GPL");
index cb501e145a42a4e85a8a12471a3ef0d8abcdf6ee..e93ea2702c73913966f2da6bd03c6f8e5762a6ec 100644 (file)
@@ -42,7 +42,7 @@
 
 
 #define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.2.9"
+#define DRV_VERSION "0.2.11"
 
 /*
  *     Private data structure to glue stuff together
@@ -355,6 +355,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d),
        PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
        PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
+       PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
        PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
index bd4ed6734edc504ca094dbcfb5d2ee6609182662..d894d9918b1d4c2acdbd3c709fa4f1a4a86030cc 100644 (file)
@@ -108,13 +108,14 @@ static struct pdc2027x_udma_timing {
 };
 
 static const struct pci_device_id pdc2027x_pci_tbl[] = {
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_100 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
-       { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), PDC_UDMA_100 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), PDC_UDMA_100 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), PDC_UDMA_133 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), PDC_UDMA_133 },
+
        { }     /* terminate list */
 };
 
index 48f43432764ebdcf71fe0d110a224d62abc8132c..5ba9eb20a6c243140515e33470332b1906aaf194 100644 (file)
@@ -385,17 +385,18 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 2);
 }
 
-static struct pci_device_id pdc[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0},
-       { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1},
-       { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1},
-       { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2},
-       { PCI_DEVICE(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2},
-       { 0, },
+static const struct pci_device_id pdc[] = {
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 },
+       { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 },
+
+       { },
 };
 
 static struct pci_driver pdc_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = pdc,
        .probe          = pdc_init_one,
        .remove         = ata_pci_remove_one
@@ -406,13 +407,11 @@ static int __init pdc_init(void)
        return pci_register_driver(&pdc_pci_driver);
 }
 
-
 static void __exit pdc_exit(void)
 {
        pci_unregister_driver(&pdc_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
 MODULE_LICENSE("GPL");
index c20bcf43ed6d3ea9f4d2b6f129eec98ae23515a5..1af83d7694d5fc704adc1525551302eabd382970 100644 (file)
@@ -300,7 +300,8 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 }
 
 static const struct pci_device_id radisys_pci_tbl[] = {
-       { 0x1331, 0x8201, PCI_ANY_ID, PCI_ANY_ID, },
+       { PCI_VDEVICE(RADISYS, 0x8201), },
+
        { }     /* terminate list */
 };
 
@@ -321,7 +322,6 @@ static void __exit radisys_exit(void)
        pci_unregister_driver(&radisys_pci_driver);
 }
 
-
 module_init(radisys_init);
 module_exit(radisys_exit);
 
index eccc6fd45032b4992091d74ddb2a608640186bea..4533b6357d99ac5022af06ba02c8affd74892b3a 100644 (file)
@@ -170,20 +170,20 @@ fail:
        return -ENODEV;
 }
 
-static struct pci_device_id pata_rz1000[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
-       { PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
-       { 0, },
+static const struct pci_device_id pata_rz1000[] = {
+       { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
+       { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
+
+       { },
 };
 
 static struct pci_driver rz1000_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = pata_rz1000,
        .probe          = rz1000_init_one,
        .remove         = ata_pci_remove_one
 };
 
-
 static int __init rz1000_init(void)
 {
        return pci_register_driver(&rz1000_pci_driver);
index 107e6cd3dc0d1b9ba0179e5577bcc99e76a1d2e8..067d9d223e350f078e955e28dce39d00950ed803 100644 (file)
@@ -253,13 +253,14 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        return ata_pci_init_one(dev, port_info, 1);
 }
 
-static struct pci_device_id sc1200[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), },
-       { 0, },
+static const struct pci_device_id sc1200[] = {
+       { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_IDE), },
+
+       { },
 };
 
 static struct pci_driver sc1200_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = sc1200,
        .probe          = sc1200_init_one,
        .remove         = ata_pci_remove_one
@@ -270,13 +271,11 @@ static int __init sc1200_init(void)
        return pci_register_driver(&sc1200_pci_driver);
 }
 
-
 static void __exit sc1200_exit(void)
 {
        pci_unregister_driver(&sc1200_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox, Mark Lord");
 MODULE_DESCRIPTION("low-level driver for the NS/AMD SC1200");
 MODULE_LICENSE("GPL");
index a5c8d7e121d148ed992e25be28367d26dc02f92d..5bbf76ec14a4d7bd00c0cb323d393190d7feb9fe 100644 (file)
@@ -553,13 +553,14 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
        return ata_pci_init_one(pdev, port_info, ports);
 }
 
-static struct pci_device_id serverworks[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
-       { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
-       { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
-       { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
-       { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
-       { 0, },
+static const struct pci_device_id serverworks[] = {
+       { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
+       { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
+       { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
+       { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
+       { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
+
+       { },
 };
 
 static struct pci_driver serverworks_pci_driver = {
@@ -574,13 +575,11 @@ static int __init serverworks_init(void)
        return pci_register_driver(&serverworks_pci_driver);
 }
 
-
 static void __exit serverworks_exit(void)
 {
        pci_unregister_driver(&serverworks_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6");
 MODULE_LICENSE("GPL");
index c8b2e26db70dd309e87fdc2babcea4b45da05715..4a2b72b4be8ac07a48f0ae21a1d394a4eafdfc95 100644 (file)
@@ -348,12 +348,13 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id sil680[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), },
-       { 0, },
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
+
+       { },
 };
 
 static struct pci_driver sil680_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = sil680,
        .probe          = sil680_init_one,
        .remove         = ata_pci_remove_one
@@ -364,13 +365,11 @@ static int __init sil680_init(void)
        return pci_register_driver(&sil680_pci_driver);
 }
 
-
 static void __exit sil680_exit(void)
 {
        pci_unregister_driver(&sil680_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for SI680 PATA");
 MODULE_LICENSE("GPL");
index 17791e2785f9ca7f0def96858f8aa68de75ef234..b9ffafb4198ceacb886b91e4de6bf6f3790b7d1d 100644 (file)
@@ -988,8 +988,9 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 }
 
 static const struct pci_device_id sis_pci_tbl[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5513), },      /* SiS 5513 */
-       { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x5518), },      /* SiS 5518 */
+       { PCI_VDEVICE(SI, 0x5513), },   /* SiS 5513 */
+       { PCI_VDEVICE(SI, 0x5518), },   /* SiS 5518 */
+
        { }
 };
 
@@ -1010,7 +1011,6 @@ static void __exit sis_exit(void)
        pci_unregister_driver(&sis_pci_driver);
 }
 
-
 module_init(sis_init);
 module_exit(sis_exit);
 
index 5b762acc56877a44f3a03b80139e61b9f21a70bc..08a6dc88676fe7085ae6c0d2775479922ae38804 100644 (file)
@@ -351,9 +351,10 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
        return ata_pci_init_one(dev, port_info, 1); /* For now */
 }
 
-static struct pci_device_id sl82c105[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
-       { 0, },
+static const struct pci_device_id sl82c105[] = {
+       { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
+
+       { },
 };
 
 static struct pci_driver sl82c105_pci_driver = {
@@ -368,13 +369,11 @@ static int __init sl82c105_init(void)
        return pci_register_driver(&sl82c105_pci_driver);
 }
 
-
 static void __exit sl82c105_exit(void)
 {
        pci_unregister_driver(&sl82c105_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Sl82c105");
 MODULE_LICENSE("GPL");
index a954ed93a40ca48a4ba8b4c5d71d23c549d5fc81..9640f80e8b0d9bbb6bfdc2e9004ec3f9c9be6412 100644 (file)
@@ -248,13 +248,13 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id triflex[] = {
-       { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
-                                 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { 0, },
+       { PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), },
+
+       { },
 };
 
 static struct pci_driver triflex_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = triflex,
        .probe          = triflex_init_one,
        .remove         = ata_pci_remove_one
@@ -265,13 +265,11 @@ static int __init triflex_init(void)
        return pci_register_driver(&triflex_pci_driver);
 }
 
-
 static void __exit triflex_exit(void)
 {
        pci_unregister_driver(&triflex_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for Compaq Triflex");
 MODULE_LICENSE("GPL");
index 7b5dd2343b9a637a9bced517f635ebb133c92f8b..1e7be9eee9c3c4cf112293b59d51670b6887dfb9 100644 (file)
@@ -529,15 +529,16 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static const struct pci_device_id via[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1), },
-       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1), },
-       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410), },
-       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
-       { 0, },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
+
+       { },
 };
 
 static struct pci_driver via_pci_driver = {
-        .name          = DRV_NAME,
+       .name           = DRV_NAME,
        .id_table       = via,
        .probe          = via_init_one,
        .remove         = ata_pci_remove_one
@@ -548,13 +549,11 @@ static int __init via_init(void)
        return pci_register_driver(&via_pci_driver);
 }
 
-
 static void __exit via_exit(void)
 {
        pci_unregister_driver(&via_pci_driver);
 }
 
-
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("low-level driver for VIA PATA");
 MODULE_LICENSE("GPL");
index 0e23ecb77bc2536c0f507ddca2370696136f0cf2..81f3d219e70ed6351ebf2b818fa06fe9fe7d052e 100644 (file)
@@ -192,8 +192,7 @@ static struct ata_port_info adma_port_info[] = {
 };
 
 static const struct pci_device_id adma_ata_pci_tbl[] = {
-       { PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_1841_idx },
+       { PCI_VDEVICE(PDC, 0x1841), board_1841_idx },
 
        { }     /* terminate list */
 };
index c01496df4a99c709b7a8f13804207fe3c28149ae..e6aa1a86d5cfeb84b9539af329f3bbb5f01d04f1 100644 (file)
@@ -533,19 +533,20 @@ static const struct ata_port_info mv_port_info[] = {
 };
 
 static const struct pci_device_id mv_pci_tbl[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x},
-
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
-       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
-
-       {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x},
-       {}                      /* terminate list */
+       { PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
+       { PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
+       { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
+       { PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
+
+       { PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
+       { PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
+       { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
+       { PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
+       { PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
+
+       { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+
+       { }                     /* terminate list */
 };
 
 static struct pci_driver mv_pci_driver = {
index 8cd730fe5dd3ecf1527193c3af4049c7e80b25e2..d09d20a177908642aa944255bbae25e047341eeb 100644 (file)
@@ -106,45 +106,32 @@ enum nv_host_type
 };
 
 static const struct pci_device_id nv_pci_tbl[] = {
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
-       { PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA), NFORCE2 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA), NFORCE3 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2), NFORCE3 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA), CK804 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
+       { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC },
+       { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC },
+       { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC },
+       { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC },
        { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
                PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
        { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
                PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC },
-       { 0, } /* terminate list */
+
+       { } /* terminate list */
 };
 
 static struct pci_driver nv_pci_driver = {
index d627812ea73d3bf5d81629d3a94be308de950d2e..15c9437710fc1735e8f378856649b090f1889fba 100644 (file)
@@ -234,48 +234,31 @@ static const struct ata_port_info pdc_port_info[] = {
 };
 
 static const struct pci_device_id pdc_ata_pci_tbl[] = {
-       { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-       { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2057x },
-       { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2057x },
-       { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
-
-       { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
-       { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
-       { PCI_VENDOR_ID_PROMISE, 0x3515, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
-       { PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
-       { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
-       { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_40518 },
-
-       { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20619 },
+       { PCI_VDEVICE(PROMISE, 0x3371), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3570), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3571), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3373), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3375), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3376), board_2037x },
+       { PCI_VDEVICE(PROMISE, 0x3574), board_2057x },
+       { PCI_VDEVICE(PROMISE, 0x3d75), board_2057x },
+       { PCI_VDEVICE(PROMISE, 0x3d73), board_2037x },
+
+       { PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3d17), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
+
+       { PCI_VDEVICE(PROMISE, 0x6629), board_20619 },
 
 /* TODO: remove all associated board_20771 code, as it completely
  * duplicates board_2037x code, unless reason for separation can be
  * divined.
  */
 #if 0
-       { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20771 },
+       { PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
 #endif
 
        { }     /* terminate list */
index fa29dfe2a7b528de2eef33f648ddfb05a7225856..7f6cc3c07de5db6820d165035c1d444419b66c59 100644 (file)
@@ -185,8 +185,7 @@ static const struct ata_port_info qs_port_info[] = {
 };
 
 static const struct pci_device_id qs_ata_pci_tbl[] = {
-       { PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2068_idx },
+       { PCI_VDEVICE(PDC, 0x2068), board_2068_idx },
 
        { }     /* terminate list */
 };
index c63dbabc0cd9637d73478a0044981660870c1498..3d9fa1cc834d4ddb32d13eccb5ec60e897060b79 100644 (file)
@@ -123,13 +123,14 @@ static void sil_thaw(struct ata_port *ap);
 
 
 static const struct pci_device_id sil_pci_tbl[] = {
-       { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 },
-       { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
-       { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
-       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
+       { PCI_VDEVICE(CMD, 0x3112), sil_3112 },
+       { PCI_VDEVICE(CMD, 0x0240), sil_3112 },
+       { PCI_VDEVICE(CMD, 0x3512), sil_3512 },
+       { PCI_VDEVICE(CMD, 0x3114), sil_3114 },
+       { PCI_VDEVICE(ATI, 0x436e), sil_3112 },
+       { PCI_VDEVICE(ATI, 0x4379), sil_3112_no_sata_irq },
+       { PCI_VDEVICE(ATI, 0x437a), sil_3112_no_sata_irq },
+
        { }     /* terminate list */
 };
 
index 39cb07baebae96ea0aa6594b6da8b1f11e189913..a951f40c2f21ba365ed2866a6cee6311b260445c 100644 (file)
@@ -344,11 +344,12 @@ static int sil24_pci_device_resume(struct pci_dev *pdev);
 #endif
 
 static const struct pci_device_id sil24_pci_tbl[] = {
-       { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
-       { 0x8086, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
-       { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
-       { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
-       { 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
+       { PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 },
+       { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
+       { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
+       { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
+       { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
+
        { } /* terminate list */
 };
 
index 18d49fff8dc4a2c7dde945b045f95b2b686499ff..0738f52463a953ccd5f630f3709bdc9e649aaa7b 100644 (file)
@@ -67,13 +67,13 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id sis_pci_tbl[] = {
-       { PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
-       { PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
-       { PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
+       { PCI_VDEVICE(SI, 0x180), sis_180 },
+       { PCI_VDEVICE(SI, 0x181), sis_180 },
+       { PCI_VDEVICE(SI, 0x182), sis_180 },
+
        { }     /* terminate list */
 };
 
-
 static struct pci_driver sis_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = sis_pci_tbl,
index d6d6658d8328b0a7c4796bba71b121c93ada8356..84025a2fd5be2167d58f8a35d5349f896b3f220f 100644 (file)
@@ -469,15 +469,15 @@ err_out:
  * controller
  * */
 static const struct pci_device_id k2_sata_pci_tbl[] = {
-       { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-       { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-       { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
-       { 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
-       { 0x1166, 0x024b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
+       { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
+       { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+
        { }
 };
 
-
 static struct pci_driver k2_sata_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = k2_sata_pci_tbl,
@@ -485,19 +485,16 @@ static struct pci_driver k2_sata_pci_driver = {
        .remove                 = ata_pci_remove_one,
 };
 
-
 static int __init k2_sata_init(void)
 {
        return pci_register_driver(&k2_sata_pci_driver);
 }
 
-
 static void __exit k2_sata_exit(void)
 {
        pci_unregister_driver(&k2_sata_pci_driver);
 }
 
-
 MODULE_AUTHOR("Benjamin Herrenschmidt");
 MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
 MODULE_LICENSE("GPL");
index 091867e10ea3fcb6463fa794f0e10ec1bc1a8fb2..8c74f2ff4344eacee424ef455f9111926c6a9e40 100644 (file)
@@ -230,12 +230,11 @@ static const struct ata_port_info pdc_port_info[] = {
 };
 
 static const struct pci_device_id pdc_sata_pci_tbl[] = {
-       { PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20621 },
+       { PCI_VDEVICE(PROMISE, 0x6622), board_20621 },
+
        { }     /* terminate list */
 };
 
-
 static struct pci_driver pdc_sata_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = pdc_sata_pci_tbl,
index dd76f37be182a61b41676891a99cd471f1d343b8..5c603ca3a50a311a0041755b66ed95ecb5b0b6a3 100644 (file)
@@ -61,13 +61,13 @@ static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id uli_pci_tbl[] = {
-       { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
-       { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
-       { PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
+       { PCI_VDEVICE(AL, 0x5289), uli_5289 },
+       { PCI_VDEVICE(AL, 0x5287), uli_5287 },
+       { PCI_VDEVICE(AL, 0x5281), uli_5281 },
+
        { }     /* terminate list */
 };
 
-
 static struct pci_driver uli_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = uli_pci_tbl,
index a72a2389a11c0c88dd62f6437984d012883b1b52..f4455a1efe2d6fa5cc7d14869b7494ad543bf11e 100644 (file)
@@ -77,9 +77,9 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void vt6420_error_handler(struct ata_port *ap);
 
 static const struct pci_device_id svia_pci_tbl[] = {
-       { 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
-       { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
-       { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
+       { PCI_VDEVICE(VIA, 0x0591), vt6420 },
+       { PCI_VDEVICE(VIA, 0x3149), vt6420 },
+       { PCI_VDEVICE(VIA, 0x3249), vt6421 },
 
        { }     /* terminate list */
 };
index d0d92f33de5476ad3d6fa1d187503c6e9cfa74bd..273d88fcf980fd185418fa6f3b05b6de3ed5cf48 100644 (file)
@@ -442,16 +442,15 @@ err_out:
        return rc;
 }
 
-
 static const struct pci_device_id vsc_sata_pci_tbl[] = {
        { PCI_VENDOR_ID_VITESSE, 0x7174,
          PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
        { PCI_VENDOR_ID_INTEL, 0x3200,
          PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
+
        { }     /* terminate list */
 };
 
-
 static struct pci_driver vsc_sata_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = vsc_sata_pci_tbl,
@@ -459,19 +458,16 @@ static struct pci_driver vsc_sata_pci_driver = {
        .remove                 = ata_pci_remove_one,
 };
 
-
 static int __init vsc_sata_init(void)
 {
        return pci_register_driver(&vsc_sata_pci_driver);
 }
 
-
 static void __exit vsc_sata_exit(void)
 {
        pci_unregister_driver(&vsc_sata_pci_driver);
 }
 
-
 MODULE_AUTHOR("Jeremy Higdon");
 MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
 MODULE_LICENSE("GPL");
index 422e31d5f8e5c4627c15c88ecc38ff8627276069..17dc22282e148d89f8a526de5a52deb32cd73828 100644 (file)
@@ -207,8 +207,7 @@ config BLK_DEV_UMEM
          module will be called umem.
 
          The umem driver has not yet been allocated a MAJOR number, so
-         one is chosen dynamically.  Use "devfs" or look in /proc/devices
-         for the device number
+         one is chosen dynamically.
 
 config BLK_DEV_UBD
        bool "Virtual block device"
@@ -407,7 +406,7 @@ config BLK_DEV_RAM_BLOCKSIZE
        depends on BLK_DEV_RAM
        default "1024"
        help
-         The default value is 1024 kilobytes.  PAGE_SIZE is a much more
+         The default value is 1024 bytes.  PAGE_SIZE is a much more
          efficient choice however.  The default is kept to ensure initrd
          setups function - apparently needed by the rd_load_image routine
          that supposes the filesystem in the image uses a 1024 blocksize.
index a6b2aa67c9b264869b71720971b4566b171ec71f..f2904f67af4711484fc0ca99c74d8dc462103d76 100644 (file)
@@ -62,6 +62,8 @@
 
 #include <asm/uaccess.h>
 
+#define DRIVER_NAME    "pktcdvd"
+
 #if PACKET_DEBUG
 #define DPRINTK(fmt, args...) printk(KERN_NOTICE fmt, ##args)
 #else
@@ -80,7 +82,7 @@
 
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
 static struct proc_dir_entry *pkt_proc;
-static int pkt_major;
+static int pktdev_major;
 static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */
 static mempool_t *psd_pool;
 
@@ -89,7 +91,7 @@ static void pkt_bio_finished(struct pktcdvd_device *pd)
 {
        BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0);
        if (atomic_dec_and_test(&pd->cdrw.pending_bios)) {
-               VPRINTK("pktcdvd: queue empty\n");
+               VPRINTK(DRIVER_NAME": queue empty\n");
                atomic_set(&pd->iosched.attention, 1);
                wake_up(&pd->wqueue);
        }
@@ -400,7 +402,7 @@ static void pkt_dump_sense(struct packet_command *cgc)
        int i;
        struct request_sense *sense = cgc->sense;
 
-       printk("pktcdvd:");
+       printk(DRIVER_NAME":");
        for (i = 0; i < CDROM_PACKET_SIZE; i++)
                printk(" %02x", cgc->cmd[i]);
        printk(" - ");
@@ -528,7 +530,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                                need_write_seek = 0;
                        if (need_write_seek && reads_queued) {
                                if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-                                       VPRINTK("pktcdvd: write, waiting\n");
+                                       VPRINTK(DRIVER_NAME": write, waiting\n");
                                        break;
                                }
                                pkt_flush_cache(pd);
@@ -537,7 +539,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                } else {
                        if (!reads_queued && writes_queued) {
                                if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-                                       VPRINTK("pktcdvd: read, waiting\n");
+                                       VPRINTK(DRIVER_NAME": read, waiting\n");
                                        break;
                                }
                                pd->iosched.writing = 1;
@@ -600,7 +602,7 @@ static int pkt_set_segment_merging(struct pktcdvd_device *pd, request_queue_t *q
                set_bit(PACKET_MERGE_SEGS, &pd->flags);
                return 0;
        } else {
-               printk("pktcdvd: cdrom max_phys_segments too small\n");
+               printk(DRIVER_NAME": cdrom max_phys_segments too small\n");
                return -EIO;
        }
 }
@@ -1049,7 +1051,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
        for (f = 0; f < pkt->frames; f++)
                if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
                        BUG();
-       VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
+       VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt);
 
        atomic_set(&pkt->io_wait, 1);
        pkt->w_bio->bi_rw = WRITE;
@@ -1286,7 +1288,7 @@ work_to_do:
 
 static void pkt_print_settings(struct pktcdvd_device *pd)
 {
-       printk("pktcdvd: %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
+       printk(DRIVER_NAME": %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
        printk("%u blocks, ", pd->settings.size >> 2);
        printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2');
 }
@@ -1471,7 +1473,7 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd)
                /*
                 * paranoia
                 */
-               printk("pktcdvd: write mode wrong %d\n", wp->data_block_type);
+               printk(DRIVER_NAME": write mode wrong %d\n", wp->data_block_type);
                return 1;
        }
        wp->packet_size = cpu_to_be32(pd->settings.size >> 2);
@@ -1515,7 +1517,7 @@ static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti)
        if (ti->rt == 1 && ti->blank == 0)
                return 1;
 
-       printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
+       printk(DRIVER_NAME": bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
        return 0;
 }
 
@@ -1533,7 +1535,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
                case 0x12: /* DVD-RAM */
                        return 1;
                default:
-                       VPRINTK("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
+                       VPRINTK(DRIVER_NAME": Wrong disc profile (%x)\n", pd->mmc3_profile);
                        return 0;
        }
 
@@ -1542,22 +1544,22 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
         * but i'm not sure, should we leave this to user apps? probably.
         */
        if (di->disc_type == 0xff) {
-               printk("pktcdvd: Unknown disc. No track?\n");
+               printk(DRIVER_NAME": Unknown disc. No track?\n");
                return 0;
        }
 
        if (di->disc_type != 0x20 && di->disc_type != 0) {
-               printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type);
+               printk(DRIVER_NAME": Wrong disc type (%x)\n", di->disc_type);
                return 0;
        }
 
        if (di->erasable == 0) {
-               printk("pktcdvd: Disc not erasable\n");
+               printk(DRIVER_NAME": Disc not erasable\n");
                return 0;
        }
 
        if (di->border_status == PACKET_SESSION_RESERVED) {
-               printk("pktcdvd: Can't write to last track (reserved)\n");
+               printk(DRIVER_NAME": Can't write to last track (reserved)\n");
                return 0;
        }
 
@@ -1593,12 +1595,12 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
 
        track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */
        if ((ret = pkt_get_track_info(pd, track, 1, &ti))) {
-               printk("pktcdvd: failed get_track\n");
+               printk(DRIVER_NAME": failed get_track\n");
                return ret;
        }
 
        if (!pkt_writable_track(pd, &ti)) {
-               printk("pktcdvd: can't write to this track\n");
+               printk(DRIVER_NAME": can't write to this track\n");
                return -EROFS;
        }
 
@@ -1608,11 +1610,11 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
         */
        pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
        if (pd->settings.size == 0) {
-               printk("pktcdvd: detected zero packet size!\n");
+               printk(DRIVER_NAME": detected zero packet size!\n");
                return -ENXIO;
        }
        if (pd->settings.size > PACKET_MAX_SECTORS) {
-               printk("pktcdvd: packet size is too big\n");
+               printk(DRIVER_NAME": packet size is too big\n");
                return -EROFS;
        }
        pd->settings.fp = ti.fp;
@@ -1654,7 +1656,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
                        pd->settings.block_mode = PACKET_BLOCK_MODE2;
                        break;
                default:
-                       printk("pktcdvd: unknown data mode\n");
+                       printk(DRIVER_NAME": unknown data mode\n");
                        return -EROFS;
        }
        return 0;
@@ -1688,10 +1690,10 @@ static int pkt_write_caching(struct pktcdvd_device *pd, int set)
        cgc.buflen = cgc.cmd[8] = 2 + ((buf[0] << 8) | (buf[1] & 0xff));
        ret = pkt_mode_select(pd, &cgc);
        if (ret) {
-               printk("pktcdvd: write caching control failed\n");
+               printk(DRIVER_NAME": write caching control failed\n");
                pkt_dump_sense(&cgc);
        } else if (!ret && set)
-               printk("pktcdvd: enabled write caching on %s\n", pd->name);
+               printk(DRIVER_NAME": enabled write caching on %s\n", pd->name);
        return ret;
 }
 
@@ -1805,11 +1807,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
        }
 
        if (!buf[6] & 0x40) {
-               printk("pktcdvd: Disc type is not CD-RW\n");
+               printk(DRIVER_NAME": Disc type is not CD-RW\n");
                return 1;
        }
        if (!buf[6] & 0x4) {
-               printk("pktcdvd: A1 values on media are not valid, maybe not CDRW?\n");
+               printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n");
                return 1;
        }
 
@@ -1829,14 +1831,14 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
                        *speed = us_clv_to_speed[sp];
                        break;
                default:
-                       printk("pktcdvd: Unknown disc sub-type %d\n",st);
+                       printk(DRIVER_NAME": Unknown disc sub-type %d\n",st);
                        return 1;
        }
        if (*speed) {
-               printk("pktcdvd: Max. media speed: %d\n",*speed);
+               printk(DRIVER_NAME": Max. media speed: %d\n",*speed);
                return 0;
        } else {
-               printk("pktcdvd: Unknown speed %d for sub-type %d\n",sp,st);
+               printk(DRIVER_NAME": Unknown speed %d for sub-type %d\n",sp,st);
                return 1;
        }
 }
@@ -1847,7 +1849,7 @@ static int pkt_perform_opc(struct pktcdvd_device *pd)
        struct request_sense sense;
        int ret;
 
-       VPRINTK("pktcdvd: Performing OPC\n");
+       VPRINTK(DRIVER_NAME": Performing OPC\n");
 
        init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
        cgc.sense = &sense;
@@ -1865,12 +1867,12 @@ static int pkt_open_write(struct pktcdvd_device *pd)
        unsigned int write_speed, media_write_speed, read_speed;
 
        if ((ret = pkt_probe_settings(pd))) {
-               VPRINTK("pktcdvd: %s failed probe\n", pd->name);
+               VPRINTK(DRIVER_NAME": %s failed probe\n", pd->name);
                return ret;
        }
 
        if ((ret = pkt_set_write_settings(pd))) {
-               DPRINTK("pktcdvd: %s failed saving write settings\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s failed saving write settings\n", pd->name);
                return -EIO;
        }
 
@@ -1882,26 +1884,26 @@ static int pkt_open_write(struct pktcdvd_device *pd)
                case 0x13: /* DVD-RW */
                case 0x1a: /* DVD+RW */
                case 0x12: /* DVD-RAM */
-                       DPRINTK("pktcdvd: write speed %ukB/s\n", write_speed);
+                       DPRINTK(DRIVER_NAME": write speed %ukB/s\n", write_speed);
                        break;
                default:
                        if ((ret = pkt_media_speed(pd, &media_write_speed)))
                                media_write_speed = 16;
                        write_speed = min(write_speed, media_write_speed * 177);
-                       DPRINTK("pktcdvd: write speed %ux\n", write_speed / 176);
+                       DPRINTK(DRIVER_NAME": write speed %ux\n", write_speed / 176);
                        break;
        }
        read_speed = write_speed;
 
        if ((ret = pkt_set_speed(pd, write_speed, read_speed))) {
-               DPRINTK("pktcdvd: %s couldn't set write speed\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s couldn't set write speed\n", pd->name);
                return -EIO;
        }
        pd->write_speed = write_speed;
        pd->read_speed = read_speed;
 
        if ((ret = pkt_perform_opc(pd))) {
-               DPRINTK("pktcdvd: %s Optimum Power Calibration failed\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s Optimum Power Calibration failed\n", pd->name);
        }
 
        return 0;
@@ -1929,7 +1931,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
                goto out_putdev;
 
        if ((ret = pkt_get_last_written(pd, &lba))) {
-               printk("pktcdvd: pkt_get_last_written failed\n");
+               printk(DRIVER_NAME": pkt_get_last_written failed\n");
                goto out_unclaim;
        }
 
@@ -1959,11 +1961,11 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
 
        if (write) {
                if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
-                       printk("pktcdvd: not enough memory for buffers\n");
+                       printk(DRIVER_NAME": not enough memory for buffers\n");
                        ret = -ENOMEM;
                        goto out_unclaim;
                }
-               printk("pktcdvd: %lukB available on disc\n", lba << 1);
+               printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
        }
 
        return 0;
@@ -1983,7 +1985,7 @@ out:
 static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
 {
        if (flush && pkt_flush_cache(pd))
-               DPRINTK("pktcdvd: %s not flushing cache\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s not flushing cache\n", pd->name);
 
        pkt_lock_door(pd, 0);
 
@@ -2006,7 +2008,7 @@ static int pkt_open(struct inode *inode, struct file *file)
        struct pktcdvd_device *pd = NULL;
        int ret;
 
-       VPRINTK("pktcdvd: entering open\n");
+       VPRINTK(DRIVER_NAME": entering open\n");
 
        mutex_lock(&ctl_mutex);
        pd = pkt_find_dev_from_minor(iminor(inode));
@@ -2040,7 +2042,7 @@ static int pkt_open(struct inode *inode, struct file *file)
 out_dec:
        pd->refcnt--;
 out:
-       VPRINTK("pktcdvd: failed open (%d)\n", ret);
+       VPRINTK(DRIVER_NAME": failed open (%d)\n", ret);
        mutex_unlock(&ctl_mutex);
        return ret;
 }
@@ -2088,7 +2090,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
 
        pd = q->queuedata;
        if (!pd) {
-               printk("pktcdvd: %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
+               printk(DRIVER_NAME": %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
                goto end_io;
        }
 
@@ -2110,13 +2112,13 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
        }
 
        if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
-               printk("pktcdvd: WRITE for ro device %s (%llu)\n",
+               printk(DRIVER_NAME": WRITE for ro device %s (%llu)\n",
                        pd->name, (unsigned long long)bio->bi_sector);
                goto end_io;
        }
 
        if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) {
-               printk("pktcdvd: wrong bio size\n");
+               printk(DRIVER_NAME": wrong bio size\n");
                goto end_io;
        }
 
@@ -2319,7 +2321,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        struct block_device *bdev;
 
        if (pd->pkt_dev == dev) {
-               printk("pktcdvd: Recursive setup not allowed\n");
+               printk(DRIVER_NAME": Recursive setup not allowed\n");
                return -EBUSY;
        }
        for (i = 0; i < MAX_WRITERS; i++) {
@@ -2327,11 +2329,11 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
                if (!pd2)
                        continue;
                if (pd2->bdev->bd_dev == dev) {
-                       printk("pktcdvd: %s already setup\n", bdevname(pd2->bdev, b));
+                       printk(DRIVER_NAME": %s already setup\n", bdevname(pd2->bdev, b));
                        return -EBUSY;
                }
                if (pd2->pkt_dev == dev) {
-                       printk("pktcdvd: Can't chain pktcdvd devices\n");
+                       printk(DRIVER_NAME": Can't chain pktcdvd devices\n");
                        return -EBUSY;
                }
        }
@@ -2354,7 +2356,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        atomic_set(&pd->cdrw.pending_bios, 0);
        pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name);
        if (IS_ERR(pd->cdrw.thread)) {
-               printk("pktcdvd: can't start kernel thread\n");
+               printk(DRIVER_NAME": can't start kernel thread\n");
                ret = -ENOMEM;
                goto out_mem;
        }
@@ -2364,7 +2366,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
                proc->data = pd;
                proc->proc_fops = &pkt_proc_fops;
        }
-       DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
+       DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
        return 0;
 
 out_mem:
@@ -2401,7 +2403,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
 
        default:
-               VPRINTK("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
+               VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
                return -ENOTTY;
        }
 
@@ -2446,7 +2448,7 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
                if (!pkt_devs[idx])
                        break;
        if (idx == MAX_WRITERS) {
-               printk("pktcdvd: max %d writers supported\n", MAX_WRITERS);
+               printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
                return -EBUSY;
        }
 
@@ -2470,15 +2472,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
 
        spin_lock_init(&pd->lock);
        spin_lock_init(&pd->iosched.lock);
-       sprintf(pd->name, "pktcdvd%d", idx);
+       sprintf(pd->name, DRIVER_NAME"%d", idx);
        init_waitqueue_head(&pd->wqueue);
        pd->bio_queue = RB_ROOT;
 
-       disk->major = pkt_major;
+       disk->major = pktdev_major;
        disk->first_minor = idx;
        disk->fops = &pktcdvd_ops;
        disk->flags = GENHD_FL_REMOVABLE;
-       sprintf(disk->disk_name, "pktcdvd%d", idx);
+       sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
        disk->private_data = pd;
        disk->queue = blk_alloc_queue(GFP_KERNEL);
        if (!disk->queue)
@@ -2520,7 +2522,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
                        break;
        }
        if (idx == MAX_WRITERS) {
-               DPRINTK("pktcdvd: dev not setup\n");
+               DPRINTK(DRIVER_NAME": dev not setup\n");
                return -ENXIO;
        }
 
@@ -2533,7 +2535,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
        blkdev_put(pd->bdev);
 
        remove_proc_entry(pd->name, pkt_proc);
-       DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
+       DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name);
 
        del_gendisk(pd->disk);
        blk_cleanup_queue(pd->disk->queue);
@@ -2610,7 +2612,7 @@ static struct file_operations pkt_ctl_fops = {
 
 static struct miscdevice pkt_misc = {
        .minor          = MISC_DYNAMIC_MINOR,
-       .name           = "pktcdvd",
+       .name           = DRIVER_NAME,
        .fops           = &pkt_ctl_fops
 };
 
@@ -2623,28 +2625,28 @@ static int __init pkt_init(void)
        if (!psd_pool)
                return -ENOMEM;
 
-       ret = register_blkdev(pkt_major, "pktcdvd");
+       ret = register_blkdev(pktdev_major, DRIVER_NAME);
        if (ret < 0) {
-               printk("pktcdvd: Unable to register block device\n");
+               printk(DRIVER_NAME": Unable to register block device\n");
                goto out2;
        }
-       if (!pkt_major)
-               pkt_major = ret;
+       if (!pktdev_major)
+               pktdev_major = ret;
 
        ret = misc_register(&pkt_misc);
        if (ret) {
-               printk("pktcdvd: Unable to register misc device\n");
+               printk(DRIVER_NAME": Unable to register misc device\n");
                goto out;
        }
 
        mutex_init(&ctl_mutex);
 
-       pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
+       pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver);
 
        return 0;
 
 out:
-       unregister_blkdev(pkt_major, "pktcdvd");
+       unregister_blkdev(pktdev_major, DRIVER_NAME);
 out2:
        mempool_destroy(psd_pool);
        return ret;
@@ -2652,9 +2654,9 @@ out2:
 
 static void __exit pkt_exit(void)
 {
-       remove_proc_entry("pktcdvd", proc_root_driver);
+       remove_proc_entry(DRIVER_NAME, proc_root_driver);
        misc_deregister(&pkt_misc);
-       unregister_blkdev(pkt_major, "pktcdvd");
+       unregister_blkdev(pktdev_major, DRIVER_NAME);
        mempool_destroy(psd_pool);
 }
 
index b38c84a7a8e3e30e7d8080fafa209562d7e7f673..2a0c50d84fc513842aedb86caf313e64cb9d11b9 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/drivers/cdrom/cdrom.c
+/* linux/drivers/cdrom/cdrom.c
    Copyright (c) 1996, 1997 David A. van Leeuwen.
    Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
    Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
index d0e92ed0a367292d271d625b1b80069fed195fd6..486f97c3f4e5a7d186d3370a9a6a379eb44eed64 100644 (file)
@@ -112,17 +112,6 @@ static struct serial_state rs_table[1];
 
 #define NR_PORTS ARRAY_SIZE(rs_table)
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-
 #include <asm/uaccess.h>
 
 #define serial_isroot()        (capable(CAP_SYS_ADMIN))
@@ -912,7 +901,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count
        if (serial_paranoia_check(info, tty->name, "rs_write"))
                return 0;
 
-       if (!info->xmit.buf || !tmp_buf)
+       if (!info->xmit.buf)
                return 0;
 
        local_save_flags(flags);
@@ -1778,7 +1767,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
 {
        struct async_struct     *info;
        int                     retval, line;
-       unsigned long           page;
 
        line = tty->index;
        if ((line < 0) || (line >= NR_PORTS)) {
@@ -1798,17 +1786,6 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
 #endif
        info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
-       if (!tmp_buf) {
-               page = get_zeroed_page(GFP_KERNEL);
-               if (!page) {
-                       return -ENOMEM;
-               }
-               if (tmp_buf)
-                       free_page(page);
-               else
-                       tmp_buf = (unsigned char *) page;
-       }
-
        /*
         * If the port is the middle of closing, bail out now
         */
@@ -2090,11 +2067,6 @@ static __exit void rs_exit(void)
          kfree(info);
        }
 
-       if (tmp_buf) {
-               free_page((unsigned long) tmp_buf);
-               tmp_buf = NULL;
-       }
-
        release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
 }
 
index f85b4eb166181ba5d1777af825454601abd301aa..87b2fb5108713d63715b50340691b6176bcf4ea7 100644 (file)
@@ -747,18 +747,6 @@ static struct cyclades_port cy_port[NR_PORTS];
 
 static int cy_next_channel; /* next minor available */
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.  This buffer is
- * allocated when the first cy_open occurs.
- */
-static unsigned char *tmp_buf;
-
 /*
  * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
@@ -2466,7 +2454,6 @@ cy_open(struct tty_struct *tty, struct file * filp)
 {
   struct cyclades_port  *info;
   int retval, line;
-  unsigned long page;
 
     line = tty->index;
     if ((line < 0) || (NR_PORTS <= line)){
@@ -2545,15 +2532,6 @@ cy_open(struct tty_struct *tty, struct file * filp)
     printk("cyc:cy_open (%d): incrementing count to %d\n",
         current->pid, info->count);
 #endif
-    if (!tmp_buf) {
-       page = get_zeroed_page(GFP_KERNEL);
-       if (!page)
-           return -ENOMEM;
-       if (tmp_buf)
-           free_page(page);
-       else
-           tmp_buf = (unsigned char *) page;
-    }
 
     /*
      * If the port is the middle of closing, bail out now
@@ -2832,7 +2810,7 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count)
         return 0;
     }
         
-    if (!info->xmit_buf || !tmp_buf)
+    if (!info->xmit_buf)
        return 0;
 
     CY_LOCK(info, flags);
@@ -5490,10 +5468,6 @@ cy_cleanup_module(void)
 #endif
         }
     }
-    if (tmp_buf) {
-       free_page((unsigned long) tmp_buf);
-       tmp_buf = NULL;
-    }
 } /* cy_cleanup_module */
 
 module_init(cy_init);
index 3baa2ab8cbd49421818ed995bf38a4935af1da34..c3f95583a120ca1ca89ebd7d3d4259f024255df7 100644 (file)
@@ -1113,11 +1113,8 @@ static void __exit epca_module_exit(void)
                ch = card_ptr[crd];
                for (count = 0; count < bd->numports; count++, ch++) 
                { /* Begin for each port */
-                       if (ch) {
-                               if (ch->tty)
-                                       tty_hangup(ch->tty);
-                               kfree(ch->tmp_buf);
-                       }
+                       if (ch && ch->tty)
+                               tty_hangup(ch->tty);
                } /* End for each port */
        } /* End for each card */
        pci_unregister_driver (&epca_driver);
@@ -1635,16 +1632,6 @@ static void post_fep_init(unsigned int crd)
                init_waitqueue_head(&ch->close_wait);
 
                spin_unlock_irqrestore(&epca_lock, flags);
-
-               ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
-               if (!ch->tmp_buf) {
-                       printk(KERN_ERR "POST FEP INIT : kmalloc failed for port 0x%x\n",i);
-                       release_region((int)bd->port, 4);
-                       while(i-- > 0)
-                               kfree((ch--)->tmp_buf);
-                       return;
-               } else
-                       memset((void *)ch->tmp_buf,0,ch->txbufsize);
        } /* End for each port */
 
        printk(KERN_INFO 
index 456d6c8f94a8c6ae1644a698cd087c95617fb3b0..a297238cd3baa4231e2f1426f6ac737f1bef8f94 100644 (file)
@@ -130,7 +130,6 @@ struct channel
        unsigned long  c_oflag;
        unsigned char __iomem *txptr;
        unsigned char __iomem *rxptr;
-       unsigned char *tmp_buf;
        struct board_info           *board;
        struct board_chan           __iomem *brdchan;
        struct digi_struct          digiext;
index 4711d9b3a59545f870d769f4818f967923bf21a9..87127e49c0dbf8a07aeae5fd6cee1f5be3d0a397 100644 (file)
@@ -33,8 +33,6 @@
 
 #define DEBUG 
 
-static char *                  tmp_buf; 
-
 static int gs_debug;
 
 #ifdef DEBUG
@@ -205,7 +203,7 @@ int gs_write(struct tty_struct * tty,
        if (!tty) return -EIO;
 
        port = tty->driver_data;
-       if (!port || !port->xmit_buf || !tmp_buf)
+       if (!port || !port->xmit_buf)
                return -EIO;
 
        local_save_flags(flags);
@@ -837,24 +835,9 @@ void gs_set_termios (struct tty_struct * tty,
 int gs_init_port(struct gs_port *port)
 {
        unsigned long flags;
-       unsigned long page;
 
        func_enter ();
 
-        if (!tmp_buf) {
-               page = get_zeroed_page(GFP_KERNEL);
-               spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */
-               if (tmp_buf)
-                       free_page(page);
-               else
-                       tmp_buf = (unsigned char *) page;
-               spin_unlock_irqrestore (&port->driver_lock, flags);
-               if (!tmp_buf) {
-                       func_exit ();
-                       return -ENOMEM;
-               }
-       }
-
        if (port->flags & ASYNC_INITIALIZED) {
                func_exit ();
                return 0;
index ef71022423c9f32567f428e95e8257ec56487d99..3cf4d641a51c637c48508a2e9c10a120de86e757 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/char/rng/ixp4xx-rng.c
+ * drivers/char/hw_random/ixp4xx-rng.c
  *
  * RNG driver for Intel IXP4xx family of NPUs
  *
index a01d796d1eeb3624a4f55537d604cc9dba1cb1e3..e13dd1892bfdf95bb8c8e731528c12eab1a4fb4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * driver/char/hw_random/omap-rng.c
+ * drivers/char/hw_random/omap-rng.c
  *
  * RNG driver for TI OMAP CPU family
  *
index 70f8d19fb79f5deb4ead601bcd9afbf10a9ab59f..480251fc78e2865dd3d387e59074fcefbce77b12 100644 (file)
@@ -41,10 +41,7 @@ Example to enable the 3780i DSP using ttyS1 resources:
 Accessing the driver
 --------------------
 
-You must also create a node for the driver.  Without devfs:
+You must also create a node for the driver:
   mkdir -p /dev/modems
   mknod --mode=660 /dev/modems/mwave c 10 219
-With devfs:
-  mkdir -p /dev/modems
-  ln -s ../misc/mwave /dev/modems/mwave
 
index 214d850112fde66bcbff652fc2561926fcd16923..b0ab3f28cc6a84768b77a169bdd0b7d968f86a11 100644 (file)
@@ -81,7 +81,6 @@
 
 static struct riscom_board * IRQ_to_board[16];
 static struct tty_driver *riscom_driver;
-static unsigned char * tmp_buf;
 
 static unsigned long baud_table[] =  {
        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
@@ -1124,7 +1123,7 @@ static int rc_write(struct tty_struct * tty,
        
        bp = port_Board(port);
 
-       if (!tty || !port->xmit_buf || !tmp_buf)
+       if (!tty || !port->xmit_buf)
                return 0;
 
        save_flags(flags);
@@ -1612,11 +1611,6 @@ static inline int rc_init_drivers(void)
        if (!riscom_driver)     
                return -ENOMEM;
        
-       if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
-               printk(KERN_ERR "rc: Couldn't get free page.\n");
-               put_tty_driver(riscom_driver);
-               return 1;
-       }
        memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
        riscom_driver->owner = THIS_MODULE;
        riscom_driver->name = "ttyL";
@@ -1629,7 +1623,6 @@ static inline int rc_init_drivers(void)
        riscom_driver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(riscom_driver, &riscom_ops);
        if ((error = tty_register_driver(riscom_driver)))  {
-               free_page((unsigned long)tmp_buf);
                put_tty_driver(riscom_driver);
                printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
                                "error = %d\n",
@@ -1657,7 +1650,6 @@ static void rc_release_drivers(void)
 
        save_flags(flags);
        cli();
-       free_page((unsigned long)tmp_buf);
        tty_unregister_driver(riscom_driver);
        put_tty_driver(riscom_driver);
        restore_flags(flags);
index b4ea1266b66300980288141975bc0392345955ee..f4809c8183ccd9acaf1dfe4dbbec145ff6700929 100644 (file)
@@ -118,17 +118,6 @@ struct cyclades_port cy_port[] = {
 };
 #define NR_PORTS        ARRAY_SIZE(cy_port)
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf = 0;
-
 /*
  * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
@@ -1132,7 +1121,7 @@ cy_put_char(struct tty_struct *tty, unsigned char ch)
     if (serial_paranoia_check(info, tty->name, "cy_put_char"))
        return;
 
-    if (!tty || !info->xmit_buf)
+    if (!info->xmit_buf)
        return;
 
     local_irq_save(flags);
@@ -1198,7 +1187,7 @@ cy_write(struct tty_struct * tty,
        return 0;
     }
        
-    if (!tty || !info->xmit_buf || !tmp_buf){
+    if (!info->xmit_buf){
         return 0;
     }
 
@@ -1983,13 +1972,6 @@ cy_open(struct tty_struct *tty, struct file * filp)
     tty->driver_data = info;
     info->tty = tty;
 
-    if (!tmp_buf) {
-       tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-       if (!tmp_buf){
-           return -ENOMEM;
-        }
-    }
-
     /*
      * Start up serial port
      */
index c91d9a660ec00c5644a6d5a0a386582209d5aecc..fd955dbd588cb75b5be420e24a644ffcedb6040e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/watchdog/ixp2000_wdt.c
+ * drivers/char/watchdog/ixp2000_wdt.c
  *
  * Watchdog driver for Intel IXP2000 network processors
  *
index db477f7123883c143cdabef88b456a8c6c400850..5864bb865cfe542e0a93cb15e7003c2de572c8fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/watchdog/ixp4xx_wdt.c
+ * drivers/char/watchdog/ixp4xx_wdt.c
  *
  * Watchdog driver for Intel IXP4xx network processors
  *
index d418b8297211fa9f7497bd09297f8c6fcad66831..22915cc46ba7fbe56ef7e52896ce74c9490b8e7a 100644 (file)
@@ -63,7 +63,7 @@ static struct clocksource cs_hrt = {
 
 static int __init init_hrt_clocksource(void)
 {
-       /* Make sure scx200 has initializedd the configuration block */
+       /* Make sure scx200 has initialized the configuration block */
        if (!scx200_cb_present())
                return -ENODEV;
 
@@ -76,7 +76,7 @@ static int __init init_hrt_clocksource(void)
        }
 
        /* write timer config */
-       outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
+       outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
             scx200_cb_base + SCx200_TMCNFG_OFFSET);
 
        if (mhz27) {
index 2caaf71d80c85566bd24d235419f6e09fa097d12..86e69b7f9122d3639e834307c5a1662e33ee8986 100644 (file)
@@ -52,8 +52,14 @@ static void handle_update(void *data);
  * The mutex locks both lists.
  */
 static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
-static BLOCKING_NOTIFIER_HEAD(cpufreq_transition_notifier_list);
+static struct srcu_notifier_head cpufreq_transition_notifier_list;
 
+static int __init init_cpufreq_transition_notifier_list(void)
+{
+       srcu_init_notifier_head(&cpufreq_transition_notifier_list);
+       return 0;
+}
+core_initcall(init_cpufreq_transition_notifier_list);
 
 static LIST_HEAD(cpufreq_governor_list);
 static DEFINE_MUTEX (cpufreq_governor_mutex);
@@ -262,14 +268,14 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
                                freqs->old = policy->cur;
                        }
                }
-               blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+               srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                CPUFREQ_PRECHANGE, freqs);
                adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
                break;
 
        case CPUFREQ_POSTCHANGE:
                adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-               blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+               srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                CPUFREQ_POSTCHANGE, freqs);
                if (likely(policy) && likely(policy->cpu == freqs->cpu))
                        policy->cur = freqs->new;
@@ -1049,7 +1055,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
                freqs.old = cpu_policy->cur;
                freqs.new = cur_freq;
 
-               blocking_notifier_call_chain(&cpufreq_transition_notifier_list,
+               srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
                                    CPUFREQ_SUSPENDCHANGE, &freqs);
                adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
 
@@ -1130,7 +1136,7 @@ static int cpufreq_resume(struct sys_device * sysdev)
                        freqs.old = cpu_policy->cur;
                        freqs.new = cur_freq;
 
-                       blocking_notifier_call_chain(
+                       srcu_notifier_call_chain(
                                        &cpufreq_transition_notifier_list,
                                        CPUFREQ_RESUMECHANGE, &freqs);
                        adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
@@ -1176,7 +1182,7 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
 
        switch (list) {
        case CPUFREQ_TRANSITION_NOTIFIER:
-               ret = blocking_notifier_chain_register(
+               ret = srcu_notifier_chain_register(
                                &cpufreq_transition_notifier_list, nb);
                break;
        case CPUFREQ_POLICY_NOTIFIER:
@@ -1208,7 +1214,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
 
        switch (list) {
        case CPUFREQ_TRANSITION_NOTIFIER:
-               ret = blocking_notifier_chain_unregister(
+               ret = srcu_notifier_chain_unregister(
                                &cpufreq_transition_notifier_list, nb);
                break;
        case CPUFREQ_POLICY_NOTIFIER:
index 731c3d5da0dc7c6bc66a33a705f9b7a2fceab90a..88f462122a30fea0c4516de34891fcb433538182 100644 (file)
@@ -64,7 +64,7 @@ config DELL_RBU
        help
         Say m if you want to have the option of updating the BIOS for your
         DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
-        supporting application to comunicate with the BIOS regarding the new
+        supporting application to communicate with the BIOS regarding the new
         image for the image update to take effect.
         See <file:Documentation/dell_rbu.txt> for more details on the driver.
 
index b4502ed65793a01a198b666ecba4fc7e45ac286a..5c261e1f92b271e17094b05242c93959503dbad4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/i386/kernel/edd.c
+ * linux/drivers/firmware/edd.c
  *  Copyright (C) 2002, 2003, 2004 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
  *  disk signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya
index 0d9667921f618494f1dba82f5b1674ff18bf1c4c..510816c16da3b4e73193e4b632174442bc6413bf 100644 (file)
@@ -333,10 +333,10 @@ config I2C_PARPORT_LIGHT
 
          This driver is a light version of i2c-parport.  It doesn't depend
          on the parport driver, and uses direct I/O access instead.  This
-         might be prefered on embedded systems where wasting memory for
+         might be preferred on embedded systems where wasting memory for
          the clean but heavy parport handling is not an option.  The
          drawback is a reduced portability and the impossibility to
-         dasiy-chain other parallel port devices.
+         daisy-chain other parallel port devices.
          
          Don't say Y here if you said Y or M to i2c-parport.  Saying M to
          both is possible but both modules should not be loaded at the same
index 5bccb5d68318b6ea5fdfc0387a3136138d8bb20b..80d4ba1bdfecd80e5edb400e046673de54026af4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-ibm_iic.c
+ * drivers/i2c/busses/i2c-ibm_iic.c
  *
  * Support for the IIC peripheral on IBM PPC 4xx
  *
index 2b3219d00e92546a2ac190fbd67feb062e8d1f6a..59d7b437f7ff3901683b8cfac9ff6930e5cfff71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-ibm_iic.h
+ * drivers/i2c/busses/i2c-ibm_iic.h
  *
  * Support for the IIC peripheral on IBM PPC 4xx
  * 
index ab573254a8aa305c1703f4005b9477e296819397..1ce01fb0ac09f1139d04480fb9824f738e44f81f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/i2c/i2c-adap-ixp4xx.c
+ * drivers/i2c/busses/i2c-ixp4xx.c
  *
  * Intel's IXP4xx XScale NPU chipsets (IXP420, 421, 422, 425) do not have
  * an on board I2C controller but provide 16 GPIO pins that are often
index 8b65a5cf8251f1791f389750518529f7e0e69ec6..8ddbae4fafe6bfd49e57ad47533a4066e27e46c8 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/drivers/i2c/scx200_i2c.c 
+/* linux/drivers/i2c/busses/scx200_i2c.c
 
    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
 
index 15955996a1f34c7ed33b00e5658b30ae4a3c3f2c..608ca871744b1a7e4ca81ec468e9fc8702343fe0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/ide/ide-h8300.c
+ * drivers/ide/h8300/ide-h8300.c
  * H8/300 generic IDE interface
  */
 
index 31ad79f52df72386b5b99ec334353dd8d3240e5b..91c5344a945d5375e14103743990d19ca86c6792 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/ide-pmac.c
+ * linux/drivers/ide/ppc/pmac.c
  *
  * Support for IDE interfaces on PowerMacs.
  * These IDE interfaces are memory-mapped and have a DBDMA channel
index 2769e505f051530cb676cf60df41b59a34161ceb..672b92ef9f21cdd6e3cd939125d43734bcb4f0d4 100644 (file)
@@ -140,7 +140,7 @@ config IEEE1394_SBP2_PHYS_DMA
        help
          This builds sbp2 for use with non-OHCI host adapters which do not
          support physical DMA or for when ohci1394 is run with phys_dma=0.
-         Physical DMA is data movement without assistence of the drivers'
+         Physical DMA is data movement without assistance of the drivers'
          interrupt handlers.  This option includes the interrupt handlers
          that are required in absence of this hardware feature.
 
index d74653d7de1c3b6aecf59ec9f9c7a0604ebd3ebd..c75322d820d42815cacd872e5574f1432abe695c 100644 (file)
@@ -26,7 +26,7 @@ config INFINIBAND_IPOIB_DEBUG_DATA
        bool "IP-over-InfiniBand data path debugging"
        depends on INFINIBAND_IPOIB_DEBUG
        ---help---
-         This option compiles debugging code into the the data path
+         This option compiles debugging code into the data path
          of the IPoIB driver.  The output can be turned on via the
          data_debug_level module parameter; however, even with output
          turned off, this debugging code will have some performance
index 67519ef0ef9551d5cd3fe5b705954eb05814046a..271263443c37c1405cf014fd43ba607cf70cbff5 100644 (file)
@@ -32,7 +32,7 @@ config JOYSTICK_ANALOG
          module will be called analog.
 
 config JOYSTICK_A3D
-       tristate "Assasin 3D and MadCatz Panther devices"
+       tristate "Assassin 3D and MadCatz Panther devices"
        select GAMEPORT
        help
          Say Y here if you have an FPGaming or MadCatz controller using the
index c62e00c79dec81a80135b6a9702dd65e3d0e987a..679bde34d2478f058330711322ca03c7bf51b6ba 100644 (file)
@@ -177,7 +177,7 @@ config KEYBOARD_HIL_OLD
          However, it has been thoroughly tested and is stable.
 
          If you want full HIL support including support for multiple
-         keyboards, mices and tablets, you have to enable the
+         keyboards, mice, and tablets, you have to enable the
          "HP System Device Controller i8042 Support" in the input/serio
          submenu.
 
index 98acf170252cfa351d67294d20dc960210a1e207..8cdbfeca5903e84b6cf82b0ad54a036a83efd920 100644 (file)
@@ -115,9 +115,9 @@ config HP_SDC
        depends on GSC && SERIO
        default y
        ---help---
-         This option enables supports for the the "System Device
+         This option enables support for the "System Device
          Controller", an i8042 carrying microcode to manage a
-         few miscellanous devices on some Hewlett Packard systems.
+         few miscellaneous devices on some Hewlett Packard systems.
          The SDC itself contains a 10ms resolution timer/clock capable
          of delivering interrupts on a periodic and one-shot basis.
          The SDC may also be connected to a battery-backed real-time
index 51e66bc64208c77b68bf572eeaf2410c6bad8077..01d4afd9d8431a8d31332d390581fad16444105d 100644 (file)
@@ -47,7 +47,7 @@ config ISDN_DIVAS_MAINT
        tristate "DIVA Maint driver support"
        depends on ISDN_DIVAS && m
        help
-         Enable Divas Maintainance driver.
+         Enable Divas Maintenance driver.
 
 endmenu
 
index 6dfc94122dd901232fafa61399a457c3aec5b648..eb57a988e0488aac6d5a7f13c48cda909923111c 100644 (file)
@@ -321,7 +321,7 @@ config HISAX_HFC_PCI
        help
          This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
-         For more informations see under
+         For more information see under
          <file:Documentation/isdn/README.hfc-pci>.
 
 config HISAX_W6692
index e039c3a0f2a2d2c2d239f849b80da8ae454f1c20..1f4d80c5e5a68bc74f1a9c5d60c3cc0f86e7e9cb 100644 (file)
@@ -1,4 +1,4 @@
-/* 2001/10/02
+/* drivers/isdn/hisax/amd7930_fn.h
  *
  * gerdes_amd7930.h     Header-file included by
  *                      gerdes_amd7930.c
index 489022bdef7b5737af85b5a5b1da79c5f1288812..0945336c28daa61762225e324361400cf7e0d641 100644 (file)
@@ -13,7 +13,6 @@
  *
  */
 
-
 #include <linux/init.h>
 #include "hisax.h"
 #include "isac.h"
@@ -45,33 +44,31 @@ static const char *niccy_revision = "$Revision: 1.21.2.4 $";
 #define PCI_IRQ_DISABLE                0xff0000
 #define PCI_IRQ_ASSERT         0x800000
 
-static inline u_char
-readreg(unsigned int ale, unsigned int adr, u_char off)
+static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off)
 {
        register u_char ret;
 
        byteout(ale, off);
        ret = bytein(adr);
-       return (ret);
+       return ret;
 }
 
-static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+static inline void readfifo(unsigned int ale, unsigned int adr, u_char off,
+               u_char *data, int size)
 {
        byteout(ale, off);
        insb(adr, data, size);
 }
 
-
-static inline void
-writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
+static inline void writereg(unsigned int ale, unsigned int adr, u_char off,
+               u_char data)
 {
        byteout(ale, off);
        byteout(adr, data);
 }
 
-static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+static inline void writefifo(unsigned int ale, unsigned int adr, u_char off,
+               u_char *data, int size)
 {
        byteout(ale, off);
        outsb(adr, data, size);
@@ -79,39 +76,34 @@ writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int siz
 
 /* Interface functions */
 
-static u_char
-ReadISAC(struct IsdnCardState *cs, u_char offset)
+static u_char ReadISAC(struct IsdnCardState *cs, u_char offset)
 {
-       return (readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset));
+       return readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset);
 }
 
-static void
-WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
+static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
        writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value);
 }
 
-static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 {
        readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
 
-static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 {
        writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
 
-static u_char
-ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
+static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
-       return (readreg(cs->hw.niccy.hscx_ale,
-                       cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0)));
+       return readreg(cs->hw.niccy.hscx_ale,
+                       cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0));
 }
 
-static void
-WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
+static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset,
+               u_char value)
 {
        writereg(cs->hw.niccy.hscx_ale,
                 cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value);
@@ -130,8 +122,8 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 
 #include "hscx_irq.c"
 
-static irqreturn_t
-niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t niccy_interrupt(int intno, void *dev_id,
+               struct pt_regs *regs)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
@@ -141,21 +133,23 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        if (cs->subtyp == NICCY_PCI) {
                int ival;
                ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
-               if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */
+               if (!(ival & PCI_IRQ_ASSERT)) { /* IRQ not for us (shared) */
                        spin_unlock_irqrestore(&cs->lock, flags);
                        return IRQ_NONE;
                }
                outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
        }
-       val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+       val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
+                       HSCX_ISTA + 0x40);
+Start_HSCX:
        if (val)
                hscx_int_main(cs, val);
        val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
        if (val)
                isac_interrupt(cs, val);
-       val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40);
+       val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
+                       HSCX_ISTA + 0x40);
        if (val) {
                if (cs->debug & L1_DEB_HSCX)
                        debugl1(cs, "HSCX IntStat after IntRoutine");
@@ -168,21 +162,21 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
                goto Start_ISAC;
        }
        writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF);
-       writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF);
+       writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,
+                0xFF);
        writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF);
        writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0);
        writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0);
-       writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0);
+       writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,0);
        spin_unlock_irqrestore(&cs->lock, flags);
        return IRQ_HANDLED;
 }
 
-static void
-release_io_niccy(struct IsdnCardState *cs)
+static void release_io_niccy(struct IsdnCardState *cs)
 {
        if (cs->subtyp == NICCY_PCI) {
                int val;
-               
+
                val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
                val &= PCI_IRQ_DISABLE;
                outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
@@ -194,8 +188,7 @@ release_io_niccy(struct IsdnCardState *cs)
        }
 }
 
-static void
-niccy_reset(struct IsdnCardState *cs)
+static void niccy_reset(struct IsdnCardState *cs)
 {
        if (cs->subtyp == NICCY_PCI) {
                int val;
@@ -207,29 +200,28 @@ niccy_reset(struct IsdnCardState *cs)
        inithscxisac(cs, 3);
 }
 
-static int
-niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
        u_long flags;
 
        switch (mt) {
-               case CARD_RESET:
-                       spin_lock_irqsave(&cs->lock, flags);
-                       niccy_reset(cs);
-                       spin_unlock_irqrestore(&cs->lock, flags);
-                       return(0);
-               case CARD_RELEASE:
-                       release_io_niccy(cs);
-                       return(0);
-               case CARD_INIT:
-                       spin_lock_irqsave(&cs->lock, flags);
-                       niccy_reset(cs);
-                       spin_unlock_irqrestore(&cs->lock, flags);
-                       return(0);
-               case CARD_TEST:
-                       return(0);
+       case CARD_RESET:
+               spin_lock_irqsave(&cs->lock, flags);
+               niccy_reset(cs);
+               spin_unlock_irqrestore(&cs->lock, flags);
+               return 0;
+       case CARD_RELEASE:
+               release_io_niccy(cs);
+               return 0;
+       case CARD_INIT:
+               spin_lock_irqsave(&cs->lock, flags);
+               niccy_reset(cs);
+               spin_unlock_irqrestore(&cs->lock, flags);
+               return 0;
+       case CARD_TEST:
+               return 0;
        }
-       return(0);
+       return 0;
 }
 
 static struct pci_dev *niccy_dev __devinitdata = NULL;
@@ -237,8 +229,7 @@ static struct pci_dev *niccy_dev __devinitdata = NULL;
 static struct pnp_card *pnp_c __devinitdata = NULL;
 #endif
 
-int __devinit
-setup_niccy(struct IsdnCard *card)
+int __devinit setup_niccy(struct IsdnCard *card)
 {
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
@@ -246,40 +237,44 @@ setup_niccy(struct IsdnCard *card)
        strcpy(tmp, niccy_revision);
        printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp));
        if (cs->typ != ISDN_CTYPE_NICCY)
-               return (0);
+               return 0;
 #ifdef __ISAPNP__
        if (!card->para[1] && isapnp_present()) {
                struct pnp_dev *pnp_d = NULL;
                int err;
 
-               if ((pnp_c = pnp_find_card(
-                       ISAPNP_VENDOR('S', 'D', 'A'),
-                       ISAPNP_FUNCTION(0x0150), pnp_c))) {
-                       if (!(pnp_d = pnp_find_dev(pnp_c,
-                               ISAPNP_VENDOR('S', 'D', 'A'),
-                               ISAPNP_FUNCTION(0x0150), pnp_d))) {
-                               printk(KERN_ERR "NiccyPnP: PnP error card found, no device\n");
-                               return (0);
+               pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'),
+                               ISAPNP_FUNCTION(0x0150), pnp_c);
+               if (pnp_c) {
+                       pnp_d = pnp_find_dev(pnp_c,
+                                       ISAPNP_VENDOR('S', 'D', 'A'),
+                                       ISAPNP_FUNCTION(0x0150), pnp_d);
+                       if (!pnp_d) {
+                               printk(KERN_ERR "NiccyPnP: PnP error card "
+                                       "found, no device\n");
+                               return 0;
                        }
                        pnp_disable_dev(pnp_d);
                        err = pnp_activate_dev(pnp_d);
-                       if (err<0) {
-                               printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-                                       __FUNCTION__, err);
-                               return(0);
+                       if (err < 0) {
+                               printk(KERN_WARNING "%s: pnp_activate_dev "
+                                       "ret(%d)\n", __FUNCTION__, err);
+                               return 0;
                        }
                        card->para[1] = pnp_port_start(pnp_d, 0);
                        card->para[2] = pnp_port_start(pnp_d, 1);
                        card->para[0] = pnp_irq(pnp_d, 0);
-                       if (!card->para[0] || !card->para[1] || !card->para[2]) {
-                               printk(KERN_ERR "NiccyPnP:some resources are missing %ld/%lx/%lx\n",
-                                       card->para[0], card->para[1], card->para[2]);
+                       if (!card->para[0] || !card->para[1] ||
+                                       !card->para[2]) {
+                               printk(KERN_ERR "NiccyPnP:some resources are "
+                                       "missing %ld/%lx/%lx\n",
+                                       card->para[0], card->para[1],
+                                       card->para[2]);
                                pnp_disable_dev(pnp_d);
-                               return(0);
+                               return 0;
                        }
-               } else {
+               } else
                        printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n");
-               }
        }
 #endif
        if (card->para[1]) {
@@ -291,50 +286,51 @@ setup_niccy(struct IsdnCard *card)
                cs->subtyp = NICCY_PNP;
                cs->irq = card->para[0];
                if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) {
-                       printk(KERN_WARNING
-                               "HiSax: %s data port %x-%x already in use\n",
-                               CardType[card->typ],
-                               cs->hw.niccy.isac,
-                               cs->hw.niccy.isac + 1);
-                       return (0);
+                       printk(KERN_WARNING "HiSax: %s data port %x-%x "
+                               "already in use\n", CardType[card->typ],
+                               cs->hw.niccy.isac, cs->hw.niccy.isac + 1);
+                       return 0;
                }
                if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) {
-                       printk(KERN_WARNING
-                               "HiSax: %s address port %x-%x already in use\n",
-                               CardType[card->typ],
+                       printk(KERN_WARNING "HiSax: %s address port %x-%x "
+                               "already in use\n", CardType[card->typ],
                                cs->hw.niccy.isac_ale,
                                cs->hw.niccy.isac_ale + 1);
                        release_region(cs->hw.niccy.isac, 2);
-                       return (0);
+                       return 0;
                }
        } else {
 #ifdef CONFIG_PCI
                u_int pci_ioaddr;
                cs->subtyp = 0;
                if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
-                       PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) {
+                                                PCI_DEVICE_ID_SATSAGEM_NICCY,
+                                                niccy_dev))) {
                        if (pci_enable_device(niccy_dev))
-                               return(0);
+                               return 0;
                        /* get IRQ */
                        if (!niccy_dev->irq) {
-                               printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n");
-                               return(0);
+                               printk(KERN_WARNING
+                                      "Niccy: No IRQ for PCI card found\n");
+                               return 0;
                        }
                        cs->irq = niccy_dev->irq;
                        cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0);
                        if (!cs->hw.niccy.cfg_reg) {
-                               printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n");
-                               return(0);
+                               printk(KERN_WARNING
+                                      "Niccy: No IO-Adr for PCI cfg found\n");
+                               return 0;
                        }
                        pci_ioaddr = pci_resource_start(niccy_dev, 1);
                        if (!pci_ioaddr) {
-                               printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n");
-                               return(0);
+                               printk(KERN_WARNING
+                                      "Niccy: No IO-Adr for PCI card found\n");
+                               return 0;
                        }
                        cs->subtyp = NICCY_PCI;
                } else {
                        printk(KERN_WARNING "Niccy: No PCI card found\n");
-                       return(0);
+                       return 0;
                }
                cs->irq_flags |= IRQF_SHARED;
                cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA;
@@ -343,29 +339,28 @@ setup_niccy(struct IsdnCard *card)
                cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
                if (!request_region(cs->hw.niccy.isac, 4, "niccy")) {
                        printk(KERN_WARNING
-                               "HiSax: %s data port %x-%x already in use\n",
-                               CardType[card->typ],
-                               cs->hw.niccy.isac,
-                               cs->hw.niccy.isac + 4);
-                       return (0);
+                              "HiSax: %s data port %x-%x already in use\n",
+                              CardType[card->typ],
+                              cs->hw.niccy.isac, cs->hw.niccy.isac + 4);
+                       return 0;
                }
                if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) {
                        printk(KERN_WARNING
                               "HiSax: %s pci port %x-%x already in use\n",
-                               CardType[card->typ],
-                               cs->hw.niccy.cfg_reg,
-                               cs->hw.niccy.cfg_reg + 0x40);
+                              CardType[card->typ],
+                              cs->hw.niccy.cfg_reg,
+                              cs->hw.niccy.cfg_reg + 0x40);
                        release_region(cs->hw.niccy.isac, 4);
-                       return (0);
+                       return 0;
                }
 #else
                printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
                printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
-               return (0);
-#endif /* CONFIG_PCI */
+               return 0;
+#endif                         /* CONFIG_PCI */
        }
        printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
-               CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI",
+               CardType[cs->typ], (cs->subtyp == 1) ? "PnP" : "PCI",
                cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
        setup_isac(cs);
        cs->readisac = &ReadISAC;
@@ -379,10 +374,10 @@ setup_niccy(struct IsdnCard *card)
        cs->irq_func = &niccy_interrupt;
        ISACVersion(cs, "Niccy:");
        if (HscxVersion(cs, "Niccy:")) {
-               printk(KERN_WARNING
-                   "Niccy: wrong HSCX versions check IO address\n");
+               printk(KERN_WARNING "Niccy: wrong HSCX versions check IO "
+                       "address\n");
                release_io_niccy(cs);
-               return (0);
+               return 0;
        }
-       return (1);
+       return 1;
 }
index d424b4452028f2fb466ea70bd98d7ca0ae20339c..aecbbe2e89a92673fb600e0d0500194cde5dcff9 100644 (file)
@@ -125,7 +125,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
 
 /**
  * led_classdev_unregister - unregisters a object of led_properties class.
- * @led_cdev: the led device to unreigister
+ * @led_cdev: the led device to unregister
  *
  * Unregisters a previously registered via led_classdev_register object.
  */
index 3b87951aa5550211b829f5ab940fb6f98262b555..6f2d449ba9836096b97fea92a4ff4cd8bcc46649 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/leds/locomo.c
+ * linux/drivers/leds/leds-locomo.c
  *
  * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
  *
index d5d649f5ccdb3a05f14309fd1e11af83c7486a9f..7f8477d3a66128add17a44a5455dea6787e7248b 100644 (file)
@@ -186,7 +186,7 @@ config THERM_ADT746X
        depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
        help
          This driver provides some thermostat and fan control for the
-          iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty
+          iBook G4, and the ATI based aluminium PowerBooks, allowing slightly
          better fan behaviour by default, and some manual control.
 
 config THERM_PM72
index efd51e01c06eb63a731b6ad508c4f94cf49d3ce3..b7fb367808d862edbb61badfc22b21c8fd66d923 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/input/adbhid.c
+ * drivers/macintosh/adbhid.c
  *
  * ADB HID driver for Power Macintosh computers.
  *
index 38a0a5741d526cc4491a2c76dbdfe786ac58f0d5..cb8281605be8f7d23bbd0769309268b5f69d7c1a 100644 (file)
@@ -4438,8 +4438,7 @@ static int md_release(struct inode *inode, struct file * file)
 {
        mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
 
-       if (!mddev)
-               BUG();
+       BUG_ON(!mddev);
        mddev_put(mddev);
 
        return 0;
index 37e4ff661b6cce263148fe7f28d1a6be719b0244..e14f4578072006e3b464668d3c8500187df76453 100644 (file)
@@ -1105,7 +1105,7 @@ static void compute_parity6(struct stripe_head *sh, int method)
                                if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
                                        wake_up(&conf->wait_for_overlap);
 
-                               if (sh->dev[i].written) BUG();
+                               BUG_ON(sh->dev[i].written);
                                sh->dev[i].written = chosen;
                        }
                break;
index b5cdd57ec6f51e9d34c07d0bb61368fe438296ab..3d778c5aba68ea8035d70c4265bd1a364039e53d 100644 (file)
@@ -56,7 +56,7 @@ config DVB_CINERGYT2_QUERY_INTERVAL
          measurements.
 
          Please keep in mind that these updates cause traffic on the tuner
-         control bus and thus may or may not affect receiption sensitivity.
+         control bus and thus may or may not affect reception sensitivity.
 
          The default value should be a safe choice for common applications.
 
index 7015517e2c1b68aa78f84dede0289807accaace2..6d96b17a7f818b018daacf163f8c8c38dbc26310 100644 (file)
@@ -195,8 +195,7 @@ config RADIO_MIROPCM20_RDS
        ---help---
          Choose Y here if you want to see RDS/RBDS information like
          RadioText, Programme Service name, Clock Time and date, Programme
-         TYpe and Traffic Announcement/Programme identification.  You also
-         need to say Y to "miroSOUND PCM20 radio" and devfs!
+         Type and Traffic Announcement/Programme identification.
 
          It's not possible to read the raw RDS packets from the device, so
          the driver cant provide an V4L interface for this.  But the
index 5c53fe62d38bcbcc666d2858d91ce4add9e12468..afb734df6e0591ac461572c9d998f670a633aac5 100644 (file)
@@ -353,7 +353,7 @@ config VIDEO_SAA6588
        help
          Support for  Radio Data System (RDS) decoder. This allows seeing
          radio station identification transmitted using this standard.
-         Currentlly, it works only with bt8x8 chips.
+         Currently, it works only with bt8x8 chips.
 
          To compile this driver as a module, choose M here: the
          module will be called saa6588.
index 51d68f32aa068f9e7fa2c39d21ac31c56b7ae463..0f9d96963618221fbf8ef43f8b298e00f92e0e95 100644 (file)
@@ -69,6 +69,6 @@ config VIDEO_CX88_VP3054
        depends on VIDEO_CX88_DVB && DVB_MT352
        ---help---
          This adds DVB-T support for cards based on the
-         Connexant 2388x chip and the MT352 demodulator,
+         Conexant 2388x chip and the MT352 demodulator,
          which also require support for the VP-3054
          Secondary I2C bus, such at DNTV Live! DVB-T Pro.
index 11f751a6bda5abf0d428d4b92d851fc7e75c1dd1..f5e8484103116045fec5912c584f46cf175ef181 100644 (file)
@@ -175,8 +175,8 @@ dev_hint
    - If a device node is already occupied, registration will fail and
      the webcam is not available.
    - You can have up to 64 video devices; be sure to make enough device
-     nodes in /dev if you want to spread the numbers (this does not apply
-     to devfs). After /dev/video9 comes /dev/video10 (not /dev/videoA).
+     nodes in /dev if you want to spread the numbers.
+     After /dev/video9 comes /dev/video10 (not /dev/videoA).
    - If a camera does not match any dev_hint, it will simply get assigned
      the first available device node, just as it used to be.
 
index 7fc692a8f5b080e8db0a7c133db23f5eced53297..3df0e7a07c46c31be7e6635f09f51f5fd489955e 100644 (file)
@@ -18,7 +18,7 @@ config IBM_ASM
          service processor board as a regular serial port. To make use of
          this feature serial driver support (CONFIG_SERIAL_8250) must be
          enabled.
-         
+
          WARNING: This software may not be supported or function
          correctly on your IBM server. Please consult the IBM ServerProven
          website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
@@ -28,5 +28,33 @@ config IBM_ASM
 
          If unsure, say N.
 
-endmenu
+config TIFM_CORE
+       tristate "TI Flash Media interface support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         If you want support for Texas Instruments(R) Flash Media adapters
+         you should select this option and then also choose an appropriate
+         host adapter, such as 'TI Flash Media PCI74xx/PCI76xx host adapter
+         support', if you have a TI PCI74xx compatible card reader, for
+         example.
+         You will also have to select some flash card format drivers. MMC/SD
+         cards are supported via 'MMC/SD Card support: TI Flash Media MMC/SD
+         Interface support (MMC_TIFM_SD)'.
+
+          To compile this driver as a module, choose M here: the module will
+         be called tifm_core.
 
+config TIFM_7XX1
+       tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)"
+       depends on PCI && TIFM_CORE && EXPERIMENTAL
+       default TIFM_CORE
+       help
+         This option enables support for Texas Instruments(R) PCI74xx and
+         PCI76xx families of Flash Media adapters, found in many laptops.
+         To make actual use of the device, you will have to select some
+         flash card format drivers, as outlined in the TIFM_CORE Help.
+
+          To compile this driver as a module, choose M here: the module will
+         be called tifm_7xx1.
+
+endmenu
index c1bf1fb04c5c5cf2007c93f8a3239de35a29659a..d65ece76095a43283de2714a8c7dc0ac9a0f1625 100644 (file)
@@ -6,3 +6,5 @@ obj- := misc.o  # Dummy rule to force built-in.o to be made
 obj-$(CONFIG_IBM_ASM)          += ibmasm/
 obj-$(CONFIG_HDPU_FEATURES)    += hdpuftrs/
 obj-$(CONFIG_LKDTM)            += lkdtm.o
+obj-$(CONFIG_TIFM_CORE)        += tifm_core.o
+obj-$(CONFIG_TIFM_7XX1)        += tifm_7xx1.o
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
new file mode 100644 (file)
index 0000000..a7ed304
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ *  tifm_7xx1.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * 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 <linux/tifm.h>
+#include <linux/dma-mapping.h>
+
+#define DRIVER_NAME "tifm_7xx1"
+#define DRIVER_VERSION "0.6"
+
+static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
+{
+       int cnt;
+       unsigned long flags;
+
+       spin_lock_irqsave(&fm->lock, flags);
+       if (!fm->inhibit_new_cards) {
+               for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+                       if (fm->sockets[cnt] == sock) {
+                               fm->remove_mask |= (1 << cnt);
+                               queue_work(fm->wq, &fm->media_remover);
+                               break;
+                       }
+               }
+       }
+       spin_unlock_irqrestore(&fm->lock, flags);
+}
+
+static void tifm_7xx1_remove_media(void *adapter)
+{
+       struct tifm_adapter *fm = adapter;
+       unsigned long flags;
+       int cnt;
+       struct tifm_dev *sock;
+
+       if (!class_device_get(&fm->cdev))
+               return;
+       spin_lock_irqsave(&fm->lock, flags);
+       for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+               if (fm->sockets[cnt] && (fm->remove_mask & (1 << cnt))) {
+                       printk(KERN_INFO DRIVER_NAME
+                              ": demand removing card from socket %d\n", cnt);
+                       sock = fm->sockets[cnt];
+                       fm->sockets[cnt] = 0;
+                       fm->remove_mask &= ~(1 << cnt);
+
+                       writel(0x0e00, sock->addr + SOCK_CONTROL);
+
+                       writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+                               fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+                       writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+                               fm->addr + FM_SET_INTERRUPT_ENABLE);
+
+                       spin_unlock_irqrestore(&fm->lock, flags);
+                       device_unregister(&sock->dev);
+                       spin_lock_irqsave(&fm->lock, flags);
+               }
+       }
+       spin_unlock_irqrestore(&fm->lock, flags);
+       class_device_put(&fm->cdev);
+}
+
+static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct tifm_adapter *fm = dev_id;
+       unsigned int irq_status;
+       unsigned int sock_irq_status, cnt;
+
+       spin_lock(&fm->lock);
+       irq_status = readl(fm->addr + FM_INTERRUPT_STATUS);
+       if (irq_status == 0 || irq_status == (~0)) {
+               spin_unlock(&fm->lock);
+               return IRQ_NONE;
+       }
+
+       if (irq_status & TIFM_IRQ_ENABLE) {
+               writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+
+               for (cnt = 0; cnt <  fm->max_sockets; cnt++) {
+                       sock_irq_status = (irq_status >> cnt) &
+                                       (TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK);
+
+                       if (fm->sockets[cnt]) {
+                               if (sock_irq_status &&
+                                               fm->sockets[cnt]->signal_irq)
+                                       sock_irq_status = fm->sockets[cnt]->
+                                               signal_irq(fm->sockets[cnt],
+                                                       sock_irq_status);
+
+                               if (irq_status & (1 << cnt))
+                                       fm->remove_mask |= 1 << cnt;
+                       } else {
+                               if (irq_status & (1 << cnt))
+                                       fm->insert_mask |= 1 << cnt;
+                       }
+               }
+       }
+       writel(irq_status, fm->addr + FM_INTERRUPT_STATUS);
+
+       if (!fm->inhibit_new_cards) {
+               if (!fm->remove_mask && !fm->insert_mask) {
+                       writel(TIFM_IRQ_ENABLE,
+                               fm->addr + FM_SET_INTERRUPT_ENABLE);
+               } else {
+                       queue_work(fm->wq, &fm->media_remover);
+                       queue_work(fm->wq, &fm->media_inserter);
+               }
+       }
+
+       spin_unlock(&fm->lock);
+       return IRQ_HANDLED;
+}
+
+static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2)
+{
+       unsigned int s_state;
+       int cnt;
+
+       writel(0x0e00, sock_addr + SOCK_CONTROL);
+
+       for (cnt = 0; cnt < 100; cnt++) {
+               if (!(TIFM_SOCK_STATE_POWERED &
+                               readl(sock_addr + SOCK_PRESENT_STATE)))
+                       break;
+               msleep(10);
+       }
+
+       s_state = readl(sock_addr + SOCK_PRESENT_STATE);
+       if (!(TIFM_SOCK_STATE_OCCUPIED & s_state))
+               return FM_NULL;
+
+       if (is_x2) {
+               writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
+       } else {
+               // SmartMedia cards need extra 40 msec
+               if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1)
+                       msleep(40);
+               writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED,
+                      sock_addr + SOCK_CONTROL);
+               msleep(10);
+               writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED,
+                       sock_addr + SOCK_CONTROL);
+       }
+
+       for (cnt = 0; cnt < 100; cnt++) {
+               if ((TIFM_SOCK_STATE_POWERED &
+                               readl(sock_addr + SOCK_PRESENT_STATE)))
+                       break;
+               msleep(10);
+       }
+
+       if (!is_x2)
+               writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED),
+                      sock_addr + SOCK_CONTROL);
+
+       return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
+}
+
+inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num)
+{
+       return base_addr + ((sock_num + 1) << 10);
+}
+
+static void tifm_7xx1_insert_media(void *adapter)
+{
+       struct tifm_adapter *fm = adapter;
+       unsigned long flags;
+       tifm_media_id media_id;
+       char *card_name = "xx";
+       int cnt, ok_to_register;
+       unsigned int insert_mask;
+       struct tifm_dev *new_sock = 0;
+
+       if (!class_device_get(&fm->cdev))
+               return;
+       spin_lock_irqsave(&fm->lock, flags);
+       insert_mask = fm->insert_mask;
+       fm->insert_mask = 0;
+       if (fm->inhibit_new_cards) {
+               spin_unlock_irqrestore(&fm->lock, flags);
+               class_device_put(&fm->cdev);
+               return;
+       }
+       spin_unlock_irqrestore(&fm->lock, flags);
+
+       for (cnt = 0; cnt < fm->max_sockets; cnt++) {
+               if (!(insert_mask & (1 << cnt)))
+                       continue;
+
+               media_id = tifm_7xx1_toggle_sock_power(tifm_7xx1_sock_addr(fm->addr, cnt),
+                                                      fm->max_sockets == 2);
+               if (media_id) {
+                       ok_to_register = 0;
+                       new_sock = tifm_alloc_device(fm, cnt);
+                       if (new_sock) {
+                               new_sock->addr = tifm_7xx1_sock_addr(fm->addr,
+                                                                       cnt);
+                               new_sock->media_id = media_id;
+                               switch (media_id) {
+                               case 1:
+                                       card_name = "xd";
+                                       break;
+                               case 2:
+                                       card_name = "ms";
+                                       break;
+                               case 3:
+                                       card_name = "sd";
+                                       break;
+                               default:
+                                       break;
+                               }
+                               snprintf(new_sock->dev.bus_id, BUS_ID_SIZE,
+                                       "tifm_%s%u:%u", card_name, fm->id, cnt);
+                               printk(KERN_INFO DRIVER_NAME
+                                       ": %s card detected in socket %d\n",
+                                       card_name, cnt);
+                               spin_lock_irqsave(&fm->lock, flags);
+                               if (!fm->sockets[cnt]) {
+                                       fm->sockets[cnt] = new_sock;
+                                       ok_to_register = 1;
+                               }
+                               spin_unlock_irqrestore(&fm->lock, flags);
+                               if (!ok_to_register ||
+                                           device_register(&new_sock->dev)) {
+                                       spin_lock_irqsave(&fm->lock, flags);
+                                       fm->sockets[cnt] = 0;
+                                       spin_unlock_irqrestore(&fm->lock,
+                                                               flags);
+                                       tifm_free_device(&new_sock->dev);
+                               }
+                       }
+               }
+               writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+                      fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+               writel((TIFM_IRQ_FIFOMASK | TIFM_IRQ_CARDMASK) << cnt,
+                      fm->addr + FM_SET_INTERRUPT_ENABLE);
+       }
+
+       writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
+       class_device_put(&fm->cdev);
+}
+
+static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
+{
+       struct tifm_adapter *fm = pci_get_drvdata(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&fm->lock, flags);
+       fm->inhibit_new_cards = 1;
+       fm->remove_mask = 0xf;
+       fm->insert_mask = 0;
+       writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+       spin_unlock_irqrestore(&fm->lock, flags);
+       flush_workqueue(fm->wq);
+
+       tifm_7xx1_remove_media(fm);
+
+       pci_set_power_state(dev, PCI_D3hot);
+        pci_disable_device(dev);
+        pci_save_state(dev);
+       return 0;
+}
+
+static int tifm_7xx1_resume(struct pci_dev *dev)
+{
+       struct tifm_adapter *fm = pci_get_drvdata(dev);
+       unsigned long flags;
+
+       pci_restore_state(dev);
+        pci_enable_device(dev);
+        pci_set_power_state(dev, PCI_D0);
+        pci_set_master(dev);
+
+       spin_lock_irqsave(&fm->lock, flags);
+       fm->inhibit_new_cards = 0;
+       writel(TIFM_IRQ_SETALL, fm->addr + FM_INTERRUPT_STATUS);
+       writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+       writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK,
+               fm->addr + FM_SET_INTERRUPT_ENABLE);
+       fm->insert_mask = 0xf;
+       spin_unlock_irqrestore(&fm->lock, flags);
+       return 0;
+}
+
+static int tifm_7xx1_probe(struct pci_dev *dev,
+                       const struct pci_device_id *dev_id)
+{
+       struct tifm_adapter *fm;
+       int pci_dev_busy = 0;
+       int rc;
+
+       rc = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+       if (rc)
+               return rc;
+
+       rc = pci_enable_device(dev);
+       if (rc)
+               return rc;
+
+       pci_set_master(dev);
+
+       rc = pci_request_regions(dev, DRIVER_NAME);
+       if (rc) {
+               pci_dev_busy = 1;
+               goto err_out;
+       }
+
+       pci_intx(dev, 1);
+
+       fm = tifm_alloc_adapter();
+       if (!fm) {
+               rc = -ENOMEM;
+               goto err_out_int;
+       }
+
+       fm->dev = &dev->dev;
+       fm->max_sockets = (dev->device == 0x803B) ? 2 : 4;
+       fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->max_sockets,
+                               GFP_KERNEL);
+       if (!fm->sockets)
+               goto err_out_free;
+
+       INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm);
+       INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm);
+       fm->eject = tifm_7xx1_eject;
+       pci_set_drvdata(dev, fm);
+
+       fm->addr = ioremap(pci_resource_start(dev, 0),
+                               pci_resource_len(dev, 0));
+       if (!fm->addr)
+               goto err_out_free;
+
+       rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm);
+       if (rc)
+               goto err_out_unmap;
+
+       rc = tifm_add_adapter(fm);
+       if (rc)
+               goto err_out_irq;
+
+       writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+       writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SETALLSOCK,
+               fm->addr + FM_SET_INTERRUPT_ENABLE);
+
+       fm->insert_mask = 0xf;
+
+       return 0;
+
+err_out_irq:
+       free_irq(dev->irq, fm);
+err_out_unmap:
+       iounmap(fm->addr);
+err_out_free:
+       pci_set_drvdata(dev, NULL);
+       tifm_free_adapter(fm);
+err_out_int:
+       pci_intx(dev, 0);
+       pci_release_regions(dev);
+err_out:
+       if (!pci_dev_busy)
+               pci_disable_device(dev);
+       return rc;
+}
+
+static void tifm_7xx1_remove(struct pci_dev *dev)
+{
+       struct tifm_adapter *fm = pci_get_drvdata(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&fm->lock, flags);
+       fm->inhibit_new_cards = 1;
+       fm->remove_mask = 0xf;
+       fm->insert_mask = 0;
+       writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+       spin_unlock_irqrestore(&fm->lock, flags);
+
+       flush_workqueue(fm->wq);
+
+       tifm_7xx1_remove_media(fm);
+
+       writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
+       free_irq(dev->irq, fm);
+
+       tifm_remove_adapter(fm);
+
+       pci_set_drvdata(dev, 0);
+
+       iounmap(fm->addr);
+       pci_intx(dev, 0);
+       pci_release_regions(dev);
+
+       pci_disable_device(dev);
+       tifm_free_adapter(fm);
+}
+
+static struct pci_device_id tifm_7xx1_pci_tbl [] = {
+       { PCI_VENDOR_ID_TI, 0x8033, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         0 }, /* xx21 - the one I have */
+        { PCI_VENDOR_ID_TI, 0x803B, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         0 }, /* xx12 - should be also supported */
+       { }
+};
+
+static struct pci_driver tifm_7xx1_driver = {
+       .name = DRIVER_NAME,
+       .id_table = tifm_7xx1_pci_tbl,
+       .probe = tifm_7xx1_probe,
+       .remove = tifm_7xx1_remove,
+       .suspend = tifm_7xx1_suspend,
+       .resume = tifm_7xx1_resume,
+};
+
+static int __init tifm_7xx1_init(void)
+{
+       return pci_register_driver(&tifm_7xx1_driver);
+}
+
+static void __exit tifm_7xx1_exit(void)
+{
+       pci_unregister_driver(&tifm_7xx1_driver);
+}
+
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia host driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, tifm_7xx1_pci_tbl);
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tifm_7xx1_init);
+module_exit(tifm_7xx1_exit);
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
new file mode 100644 (file)
index 0000000..cca5f85
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ *  tifm_core.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * 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 <linux/tifm.h>
+#include <linux/init.h>
+#include <linux/idr.h>
+
+#define DRIVER_NAME "tifm_core"
+#define DRIVER_VERSION "0.6"
+
+static DEFINE_IDR(tifm_adapter_idr);
+static DEFINE_SPINLOCK(tifm_adapter_lock);
+
+static tifm_media_id *tifm_device_match(tifm_media_id *ids,
+                       struct tifm_dev *dev)
+{
+       while (*ids) {
+               if (dev->media_id == *ids)
+                       return ids;
+               ids++;
+       }
+       return NULL;
+}
+
+static int tifm_match(struct device *dev, struct device_driver *drv)
+{
+       struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+       struct tifm_driver *fm_drv;
+
+       fm_drv = container_of(drv, struct tifm_driver, driver);
+       if (!fm_drv->id_table)
+               return -EINVAL;
+       if (tifm_device_match(fm_drv->id_table, fm_dev))
+               return 1;
+       return -ENODEV;
+}
+
+static int tifm_uevent(struct device *dev, char **envp, int num_envp,
+                      char *buffer, int buffer_size)
+{
+       struct tifm_dev *fm_dev;
+       int i = 0;
+       int length = 0;
+       const char *card_type_name[] = {"INV", "SM", "MS", "SD"};
+
+       if (!dev || !(fm_dev = container_of(dev, struct tifm_dev, dev)))
+               return -ENODEV;
+       if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                       "TIFM_CARD_TYPE=%s", card_type_name[fm_dev->media_id]))
+               return -ENOMEM;
+
+       return 0;
+}
+
+static struct bus_type tifm_bus_type = {
+       .name    = "tifm",
+       .match   = tifm_match,
+       .uevent  = tifm_uevent,
+};
+
+static void tifm_free(struct class_device *cdev)
+{
+       struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev);
+
+       kfree(fm->sockets);
+       if (fm->wq)
+               destroy_workqueue(fm->wq);
+       kfree(fm);
+}
+
+static struct class tifm_adapter_class = {
+       .name    = "tifm_adapter",
+       .release = tifm_free
+};
+
+struct tifm_adapter *tifm_alloc_adapter(void)
+{
+       struct tifm_adapter *fm;
+
+       fm = kzalloc(sizeof(struct tifm_adapter), GFP_KERNEL);
+       if (fm) {
+               fm->cdev.class = &tifm_adapter_class;
+               spin_lock_init(&fm->lock);
+               class_device_initialize(&fm->cdev);
+       }
+       return fm;
+}
+EXPORT_SYMBOL(tifm_alloc_adapter);
+
+void tifm_free_adapter(struct tifm_adapter *fm)
+{
+       class_device_put(&fm->cdev);
+}
+EXPORT_SYMBOL(tifm_free_adapter);
+
+int tifm_add_adapter(struct tifm_adapter *fm)
+{
+       int rc;
+
+       if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL))
+               return -ENOMEM;
+
+       spin_lock(&tifm_adapter_lock);
+       rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id);
+       spin_unlock(&tifm_adapter_lock);
+       if (!rc) {
+               snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id);
+               strncpy(fm->wq_name, fm->cdev.class_id, KOBJ_NAME_LEN);
+
+               fm->wq = create_singlethread_workqueue(fm->wq_name);
+               if (fm->wq)
+                       return class_device_add(&fm->cdev);
+
+               spin_lock(&tifm_adapter_lock);
+               idr_remove(&tifm_adapter_idr, fm->id);
+               spin_unlock(&tifm_adapter_lock);
+               rc = -ENOMEM;
+       }
+       return rc;
+}
+EXPORT_SYMBOL(tifm_add_adapter);
+
+void tifm_remove_adapter(struct tifm_adapter *fm)
+{
+       class_device_del(&fm->cdev);
+
+       spin_lock(&tifm_adapter_lock);
+       idr_remove(&tifm_adapter_idr, fm->id);
+       spin_unlock(&tifm_adapter_lock);
+}
+EXPORT_SYMBOL(tifm_remove_adapter);
+
+void tifm_free_device(struct device *dev)
+{
+       struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+       if (fm_dev->wq)
+               destroy_workqueue(fm_dev->wq);
+       kfree(fm_dev);
+}
+EXPORT_SYMBOL(tifm_free_device);
+
+struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id)
+{
+       struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
+
+       if (dev) {
+               spin_lock_init(&dev->lock);
+               snprintf(dev->wq_name, KOBJ_NAME_LEN, "tifm%u:%u", fm->id, id);
+               dev->wq = create_singlethread_workqueue(dev->wq_name);
+               if (!dev->wq) {
+                       kfree(dev);
+                       return 0;
+               }
+               dev->dev.parent = fm->dev;
+               dev->dev.bus = &tifm_bus_type;
+               dev->dev.release = tifm_free_device;
+       }
+       return dev;
+}
+EXPORT_SYMBOL(tifm_alloc_device);
+
+void tifm_eject(struct tifm_dev *sock)
+{
+       struct tifm_adapter *fm = dev_get_drvdata(sock->dev.parent);
+       fm->eject(fm, sock);
+}
+EXPORT_SYMBOL(tifm_eject);
+
+int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+               int direction)
+{
+       return pci_map_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
+}
+EXPORT_SYMBOL(tifm_map_sg);
+
+void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+                  int direction)
+{
+       pci_unmap_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
+}
+EXPORT_SYMBOL(tifm_unmap_sg);
+
+static int tifm_device_probe(struct device *dev)
+{
+       struct tifm_driver *drv;
+       struct tifm_dev *fm_dev;
+       int rc = 0;
+       const tifm_media_id *id;
+
+       drv = container_of(dev->driver, struct tifm_driver, driver);
+       fm_dev = container_of(dev, struct tifm_dev, dev);
+       get_device(dev);
+       if (!fm_dev->drv && drv->probe && drv->id_table) {
+               rc = -ENODEV;
+               id = tifm_device_match(drv->id_table, fm_dev);
+               if (id)
+                       rc = drv->probe(fm_dev);
+               if (rc >= 0) {
+                       rc = 0;
+                       fm_dev->drv = drv;
+               }
+       }
+       if (rc)
+               put_device(dev);
+       return rc;
+}
+
+static int tifm_device_remove(struct device *dev)
+{
+       struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev);
+       struct tifm_driver *drv = fm_dev->drv;
+
+       if (drv) {
+               if (drv->remove) drv->remove(fm_dev);
+               fm_dev->drv = 0;
+       }
+
+       put_device(dev);
+       return 0;
+}
+
+int tifm_register_driver(struct tifm_driver *drv)
+{
+       drv->driver.bus = &tifm_bus_type;
+       drv->driver.probe = tifm_device_probe;
+       drv->driver.remove = tifm_device_remove;
+
+       return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(tifm_register_driver);
+
+void tifm_unregister_driver(struct tifm_driver *drv)
+{
+       driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(tifm_unregister_driver);
+
+static int __init tifm_init(void)
+{
+       int rc = bus_register(&tifm_bus_type);
+
+       if (!rc) {
+               rc = class_register(&tifm_adapter_class);
+               if (rc)
+                       bus_unregister(&tifm_bus_type);
+       }
+
+       return rc;
+}
+
+static void __exit tifm_exit(void)
+{
+       class_unregister(&tifm_adapter_class);
+       bus_unregister(&tifm_bus_type);
+}
+
+subsys_initcall(tifm_init);
+module_exit(tifm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia core driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
index f540bd88dc5a23aa12216079cf7ad675b2eff092..ea41852ec8cd33f945eb942519fe90b680de7920 100644 (file)
@@ -109,4 +109,20 @@ config MMC_IMX
 
          If unsure, say N.
 
+config MMC_TIFM_SD
+       tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
+       depends on MMC && EXPERIMENTAL
+       select TIFM_CORE
+       help
+         Say Y here if you want to be able to access MMC/SD cards with
+         the Texas Instruments(R) Flash Media card reader, found in many
+         laptops.
+         This option 'selects' (turns on, enables) 'TIFM_CORE', but you
+         probably also need appropriate card reader host adapter, such as
+         'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support
+         (TIFM_7XX1)'.
+
+          To compile this driver as a module, choose M here: the
+         module will be called tifm_sd.
+
 endmenu
index b1f6e03e7aa9cd216a6a12ccc9518956f0cb2fbb..acfd4de0aba526f5bc220ef33c0c50643bcbc896 100644 (file)
@@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_WBSD)                += wbsd.o
 obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)         += omap.o
 obj-$(CONFIG_MMC_AT91RM9200)   += at91_mci.o
+obj-$(CONFIG_MMC_TIFM_SD)      += tifm_sd.o
 
 mmc_core-y := mmc.o mmc_sysfs.o
 mmc_core-$(CONFIG_BLOCK) += mmc_queue.o
index 5b9caa7978d34311839840243e38921255f6da4b..ee8863c123e37881e0f35ee658a15fd5e925ad31 100644 (file)
@@ -1166,9 +1166,9 @@ static void mmc_setup(struct mmc_host *host)
 void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 {
        if (delay)
-               schedule_delayed_work(&host->detect, delay);
+               mmc_schedule_delayed_work(&host->detect, delay);
        else
-               schedule_work(&host->detect);
+               mmc_schedule_work(&host->detect);
 }
 
 EXPORT_SYMBOL(mmc_detect_change);
@@ -1311,7 +1311,7 @@ EXPORT_SYMBOL(mmc_remove_host);
  */
 void mmc_free_host(struct mmc_host *host)
 {
-       flush_scheduled_work();
+       mmc_flush_scheduled_work();
        mmc_free_host_sysfs(host);
 }
 
index 97bae00292fafdfdfc7d785d9b4725603e5583d5..cd5e0ab3d84b46c62018d4ac0fa3930dd704953e 100644 (file)
@@ -18,4 +18,8 @@ struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
 int mmc_add_host_sysfs(struct mmc_host *host);
 void mmc_remove_host_sysfs(struct mmc_host *host);
 void mmc_free_host_sysfs(struct mmc_host *host);
+
+int mmc_schedule_work(struct work_struct *work);
+int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay);
+void mmc_flush_scheduled_work(void);
 #endif
index db0e8ad439a5f6c8e09f873bf5734d9bc51df217..c1293f1bda870337e38f03d34848ff6c2fce3a5e 100644 (file)
@@ -158,13 +158,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
        struct mmc_blk_data *md = mq->data;
        struct mmc_card *card = md->queue.card;
+       struct mmc_blk_request brq;
        int ret;
 
        if (mmc_card_claim_host(card))
                goto cmd_err;
 
        do {
-               struct mmc_blk_request brq;
                struct mmc_command cmd;
                u32 readcmd, writecmd;
 
@@ -278,17 +278,27 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
  cmd_err:
        mmc_card_release_host(card);
 
+       ret = 1;
+
        /*
-        * This is a little draconian, but until we get proper
-        * error handling sorted out here, its the best we can
-        * do - especially as some hosts have no idea how much
-        * data was transferred before the error occurred.
+        * For writes and where the host claims to support proper
+        * error reporting, we first ok the successful blocks.
+        *
+        * For reads we just fail the entire chunk as that should
+        * be safe in all cases.
         */
+       if (rq_data_dir(req) != READ &&
+           (card->host->caps & MMC_CAP_MULTIWRITE)) {
+               spin_lock_irq(&md->lock);
+               ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
+               spin_unlock_irq(&md->lock);
+       }
+
        spin_lock_irq(&md->lock);
-       do {
+       while (ret) {
                ret = end_that_request_chunk(req, 0,
                                req->current_nr_sectors << 9);
-       } while (ret);
+       }
 
        add_disk_randomness(req->rq_disk);
        blkdev_dequeue_request(req);
index a2a35fd946eecf8a2b9fc585b2687f39e2806e82..10cc9734eaa0ea56187259b2947bf7d42931c9bf 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/idr.h>
+#include <linux/workqueue.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -317,10 +318,41 @@ void mmc_free_host_sysfs(struct mmc_host *host)
        class_device_put(&host->class_dev);
 }
 
+static struct workqueue_struct *workqueue;
+
+/*
+ * Internal function. Schedule work in the MMC work queue.
+ */
+int mmc_schedule_work(struct work_struct *work)
+{
+       return queue_work(workqueue, work);
+}
+
+/*
+ * Internal function. Schedule delayed work in the MMC work queue.
+ */
+int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay)
+{
+       return queue_delayed_work(workqueue, work, delay);
+}
+
+/*
+ * Internal function. Flush all scheduled work from the MMC work queue.
+ */
+void mmc_flush_scheduled_work(void)
+{
+       flush_workqueue(workqueue);
+}
 
 static int __init mmc_init(void)
 {
-       int ret = bus_register(&mmc_bus_type);
+       int ret;
+
+       workqueue = create_singlethread_workqueue("kmmcd");
+       if (!workqueue)
+               return -ENOMEM;
+
+       ret = bus_register(&mmc_bus_type);
        if (ret == 0) {
                ret = class_register(&mmc_host_class);
                if (ret)
@@ -333,6 +365,7 @@ static void __exit mmc_exit(void)
 {
        class_unregister(&mmc_host_class);
        bus_unregister(&mmc_bus_type);
+       destroy_workqueue(workqueue);
 }
 
 module_init(mmc_init);
index 4dab5ec392eabf450e23d351a0b39c36f63afb68..20711acb01201e67828aa8edaea076c3ab70cf58 100644 (file)
@@ -35,6 +35,8 @@ static unsigned int debug_quirks = 0;
 
 #define SDHCI_QUIRK_CLOCK_BEFORE_RESET                 (1<<0)
 #define SDHCI_QUIRK_FORCE_DMA                          (1<<1)
+/* Controller doesn't like some resets when there is no card inserted. */
+#define SDHCI_QUIRK_NO_CARD_NO_RESET                   (1<<2)
 
 static const struct pci_device_id pci_ids[] __devinitdata = {
        {
@@ -51,7 +53,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
                .device         = PCI_DEVICE_ID_RICOH_R5C822,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .driver_data    = SDHCI_QUIRK_FORCE_DMA,
+               .driver_data    = SDHCI_QUIRK_FORCE_DMA |
+                                 SDHCI_QUIRK_NO_CARD_NO_RESET,
        },
 
        {
@@ -125,6 +128,12 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
        unsigned long timeout;
 
+       if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
+               if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+                       SDHCI_CARD_PRESENT))
+                       return;
+       }
+
        writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
 
        if (mask & SDHCI_RESET_ALL)
@@ -717,6 +726,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        } else
                sdhci_send_command(host, mrq->cmd);
 
+       mmiowb();
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -753,6 +763,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                ctrl &= ~SDHCI_CTRL_4BITBUS;
        writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
 
+       mmiowb();
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -860,6 +871,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 
        sdhci_deactivate_led(host);
 
+       mmiowb();
        spin_unlock_irqrestore(&host->lock, flags);
 
        mmc_request_done(host->mmc, mrq);
@@ -893,6 +905,7 @@ static void sdhci_timeout_timer(unsigned long data)
                }
        }
 
+       mmiowb();
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
@@ -1030,6 +1043,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs)
 
        result = IRQ_HANDLED;
 
+       mmiowb();
 out:
        spin_unlock(&host->lock);
 
@@ -1095,6 +1109,7 @@ static int sdhci_resume (struct pci_dev *pdev)
                if (chip->hosts[i]->flags & SDHCI_USE_DMA)
                        pci_set_master(pdev);
                sdhci_init(chip->hosts[i]);
+               mmiowb();
                ret = mmc_resume_host(chip->hosts[i]->mmc);
                if (ret)
                        return ret;
@@ -1168,6 +1183,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
        host = mmc_priv(mmc);
        host->mmc = mmc;
 
+       host->chip = chip;
+       chip->hosts[slot] = host;
+
        host->bar = first_bar + slot;
 
        host->addr = pci_resource_start(pdev, host->bar);
@@ -1324,8 +1342,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
        sdhci_dumpregs(host);
 #endif
 
-       host->chip = chip;
-       chip->hosts[slot] = host;
+       mmiowb();
 
        mmc_add_host(mmc);
 
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
new file mode 100644 (file)
index 0000000..6d23dc0
--- /dev/null
@@ -0,0 +1,933 @@
+/*
+ *  tifm_sd.c - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * 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 <linux/tifm.h>
+#include <linux/mmc/protocol.h>
+#include <linux/mmc/host.h>
+#include <linux/highmem.h>
+
+#define DRIVER_NAME "tifm_sd"
+#define DRIVER_VERSION "0.6"
+
+static int no_dma = 0;
+static int fixed_timeout = 0;
+module_param(no_dma, bool, 0644);
+module_param(fixed_timeout, bool, 0644);
+
+/* Constants here are mostly from OMAP5912 datasheet */
+#define TIFM_MMCSD_RESET      0x0002
+#define TIFM_MMCSD_CLKMASK    0x03ff
+#define TIFM_MMCSD_POWER      0x0800
+#define TIFM_MMCSD_4BBUS      0x8000
+#define TIFM_MMCSD_RXDE       0x8000   /* rx dma enable */
+#define TIFM_MMCSD_TXDE       0x0080   /* tx dma enable */
+#define TIFM_MMCSD_BUFINT     0x0c00   /* set bits: AE, AF */
+#define TIFM_MMCSD_DPE        0x0020   /* data timeout counted in kilocycles */
+#define TIFM_MMCSD_INAB       0x0080   /* abort / initialize command */
+#define TIFM_MMCSD_READ       0x8000
+
+#define TIFM_MMCSD_DATAMASK   0x001d   /* set bits: EOFB, BRS, CB, EOC */
+#define TIFM_MMCSD_ERRMASK    0x41e0   /* set bits: CERR, CCRC, CTO, DCRC, DTO */
+#define TIFM_MMCSD_EOC        0x0001   /* end of command phase  */
+#define TIFM_MMCSD_CB         0x0004   /* card enter busy state */
+#define TIFM_MMCSD_BRS        0x0008   /* block received/sent   */
+#define TIFM_MMCSD_EOFB       0x0010   /* card exit busy state  */
+#define TIFM_MMCSD_DTO        0x0020   /* data time-out         */
+#define TIFM_MMCSD_DCRC       0x0040   /* data crc error        */
+#define TIFM_MMCSD_CTO        0x0080   /* command time-out      */
+#define TIFM_MMCSD_CCRC       0x0100   /* command crc error     */
+#define TIFM_MMCSD_AF         0x0400   /* fifo almost full      */
+#define TIFM_MMCSD_AE         0x0800   /* fifo almost empty     */
+#define TIFM_MMCSD_CERR       0x4000   /* card status error     */
+
+#define TIFM_MMCSD_FIFO_SIZE  0x0020
+
+#define TIFM_MMCSD_RSP_R0     0x0000
+#define TIFM_MMCSD_RSP_R1     0x0100
+#define TIFM_MMCSD_RSP_R2     0x0200
+#define TIFM_MMCSD_RSP_R3     0x0300
+#define TIFM_MMCSD_RSP_R4     0x0400
+#define TIFM_MMCSD_RSP_R5     0x0500
+#define TIFM_MMCSD_RSP_R6     0x0600
+
+#define TIFM_MMCSD_RSP_BUSY   0x0800
+
+#define TIFM_MMCSD_CMD_BC     0x0000
+#define TIFM_MMCSD_CMD_BCR    0x1000
+#define TIFM_MMCSD_CMD_AC     0x2000
+#define TIFM_MMCSD_CMD_ADTC   0x3000
+
+typedef enum {
+       IDLE = 0,
+       CMD,    /* main command ended                   */
+       BRS,    /* block transfer finished              */
+       SCMD,   /* stop command ended                   */
+       CARD,   /* card left busy state                 */
+       FIFO,   /* FIFO operation completed (uncertain) */
+       READY
+} card_state_t;
+
+enum {
+       FIFO_RDY   = 0x0001,     /* hardware dependent value */
+       HOST_REG   = 0x0002,
+       EJECT      = 0x0004,
+       EJECT_DONE = 0x0008,
+       CARD_BUSY  = 0x0010,
+       OPENDRAIN  = 0x0040,     /* hardware dependent value */
+       CARD_EVENT = 0x0100,     /* hardware dependent value */
+       CARD_RO    = 0x0200,     /* hardware dependent value */
+       FIFO_EVENT = 0x10000 };  /* hardware dependent value */
+
+struct tifm_sd {
+       struct tifm_dev     *dev;
+
+       unsigned int        flags;
+       card_state_t        state;
+       unsigned int        clk_freq;
+       unsigned int        clk_div;
+       unsigned long       timeout_jiffies; // software timeout - 2 sec
+
+       struct mmc_request    *req;
+       struct work_struct    cmd_handler;
+       struct work_struct    abort_handler;
+       wait_queue_head_t     can_eject;
+
+       size_t                written_blocks;
+       char                  *buffer;
+       size_t                buffer_size;
+       size_t                buffer_pos;
+
+};
+
+static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host,
+                                       unsigned int host_status)
+{
+       struct mmc_command *cmd = host->req->cmd;
+       unsigned int t_val = 0, cnt = 0;
+
+       if (host_status & TIFM_MMCSD_BRS) {
+               /* in non-dma rx mode BRS fires when fifo is still not empty */
+               if (host->buffer && (cmd->data->flags & MMC_DATA_READ)) {
+                       while (host->buffer_size > host->buffer_pos) {
+                               t_val = readl(sock->addr + SOCK_MMCSD_DATA);
+                               host->buffer[host->buffer_pos++] = t_val & 0xff;
+                               host->buffer[host->buffer_pos++] =
+                                                       (t_val >> 8) & 0xff;
+                       }
+               }
+               return 1;
+       } else if (host->buffer) {
+               if ((cmd->data->flags & MMC_DATA_READ) &&
+                               (host_status & TIFM_MMCSD_AF)) {
+                       for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
+                               t_val = readl(sock->addr + SOCK_MMCSD_DATA);
+                               if (host->buffer_size > host->buffer_pos) {
+                                       host->buffer[host->buffer_pos++] =
+                                                       t_val & 0xff;
+                                       host->buffer[host->buffer_pos++] =
+                                                       (t_val >> 8) & 0xff;
+                               }
+                       }
+               } else if ((cmd->data->flags & MMC_DATA_WRITE)
+                          && (host_status & TIFM_MMCSD_AE)) {
+                       for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) {
+                               if (host->buffer_size > host->buffer_pos) {
+                                       t_val = host->buffer[host->buffer_pos++] & 0x00ff;
+                                       t_val |= ((host->buffer[host->buffer_pos++]) << 8)
+                                                & 0xff00;
+                                       writel(t_val,
+                                               sock->addr + SOCK_MMCSD_DATA);
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+static unsigned int tifm_sd_op_flags(struct mmc_command *cmd)
+{
+       unsigned int rc = 0;
+
+       switch (mmc_resp_type(cmd)) {
+       case MMC_RSP_NONE:
+               rc |= TIFM_MMCSD_RSP_R0;
+               break;
+       case MMC_RSP_R1B:
+               rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through
+       case MMC_RSP_R1:
+               rc |= TIFM_MMCSD_RSP_R1;
+               break;
+       case MMC_RSP_R2:
+               rc |= TIFM_MMCSD_RSP_R2;
+               break;
+       case MMC_RSP_R3:
+               rc |= TIFM_MMCSD_RSP_R3;
+               break;
+       case MMC_RSP_R6:
+               rc |= TIFM_MMCSD_RSP_R6;
+               break;
+       default:
+               BUG();
+       }
+
+       switch (mmc_cmd_type(cmd)) {
+       case MMC_CMD_BC:
+               rc |= TIFM_MMCSD_CMD_BC;
+               break;
+       case MMC_CMD_BCR:
+               rc |= TIFM_MMCSD_CMD_BCR;
+               break;
+       case MMC_CMD_AC:
+               rc |= TIFM_MMCSD_CMD_AC;
+               break;
+       case MMC_CMD_ADTC:
+               rc |= TIFM_MMCSD_CMD_ADTC;
+               break;
+       default:
+               BUG();
+       }
+       return rc;
+}
+
+static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd)
+{
+       struct tifm_dev *sock = host->dev;
+       unsigned int cmd_mask = tifm_sd_op_flags(cmd) |
+                               (host->flags & OPENDRAIN);
+
+       if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
+               cmd_mask |= TIFM_MMCSD_READ;
+
+       dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n",
+                               cmd->opcode, cmd->arg, cmd_mask);
+
+       writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH);
+       writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW);
+       writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND);
+}
+
+static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock)
+{
+       cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16)
+                      | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18);
+       cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16)
+                      | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10);
+       cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16)
+                      | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08);
+       cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16)
+                      | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00);
+}
+
+static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host,
+                                      unsigned int host_status)
+{
+       struct mmc_command *cmd = host->req->cmd;
+
+change_state:
+       switch (host->state) {
+       case IDLE:
+               return;
+       case CMD:
+               if (host_status & TIFM_MMCSD_EOC) {
+                       tifm_sd_fetch_resp(cmd, sock);
+                       if (cmd->data) {
+                               host->state = BRS;
+                       } else
+                               host->state = READY;
+                       goto change_state;
+               }
+               break;
+       case BRS:
+               if (tifm_sd_transfer_data(sock, host, host_status)) {
+                       if (!host->req->stop) {
+                               if (cmd->data->flags & MMC_DATA_WRITE) {
+                                       host->state = CARD;
+                               } else {
+                                       host->state =
+                                               host->buffer ? READY : FIFO;
+                               }
+                               goto change_state;
+                       }
+                       tifm_sd_exec(host, host->req->stop);
+                       host->state = SCMD;
+               }
+               break;
+       case SCMD:
+               if (host_status & TIFM_MMCSD_EOC) {
+                       tifm_sd_fetch_resp(host->req->stop, sock);
+                       if (cmd->error) {
+                               host->state = READY;
+                       } else if (cmd->data->flags & MMC_DATA_WRITE) {
+                               host->state = CARD;
+                       } else {
+                               host->state = host->buffer ? READY : FIFO;
+                       }
+                       goto change_state;
+               }
+               break;
+       case CARD:
+               if (!(host->flags & CARD_BUSY)
+                   && (host->written_blocks == cmd->data->blocks)) {
+                       host->state = host->buffer ? READY : FIFO;
+                       goto change_state;
+               }
+               break;
+       case FIFO:
+               if (host->flags & FIFO_RDY) {
+                       host->state = READY;
+                       host->flags &= ~FIFO_RDY;
+                       goto change_state;
+               }
+               break;
+       case READY:
+               queue_work(sock->wq, &host->cmd_handler);
+               return;
+       }
+
+       queue_delayed_work(sock->wq, &host->abort_handler,
+                               host->timeout_jiffies);
+}
+
+/* Called from interrupt handler */
+static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
+                                       unsigned int sock_irq_status)
+{
+       struct tifm_sd *host;
+       unsigned int host_status = 0, fifo_status = 0;
+       int error_code = 0;
+
+       spin_lock(&sock->lock);
+       host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
+       cancel_delayed_work(&host->abort_handler);
+
+       if (sock_irq_status & FIFO_EVENT) {
+               fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
+               writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
+
+               host->flags |= fifo_status & FIFO_RDY;
+       }
+
+       if (sock_irq_status & CARD_EVENT) {
+               host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
+               writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
+
+               if (!(host->flags & HOST_REG))
+                       queue_work(sock->wq, &host->cmd_handler);
+               if (!host->req)
+                       goto done;
+
+               if (host_status & TIFM_MMCSD_ERRMASK) {
+                       if (host_status & TIFM_MMCSD_CERR)
+                               error_code = MMC_ERR_FAILED;
+                       else if (host_status &
+                                       (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO))
+                               error_code = MMC_ERR_TIMEOUT;
+                       else if (host_status &
+                                       (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC))
+                               error_code = MMC_ERR_BADCRC;
+
+                       writel(TIFM_FIFO_INT_SETALL,
+                              sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+                       writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
+
+                       if (host->req->stop) {
+                               if (host->state == SCMD) {
+                                       host->req->stop->error = error_code;
+                               } else if(host->state == BRS) {
+                                       host->req->cmd->error = error_code;
+                                       tifm_sd_exec(host, host->req->stop);
+                                       queue_delayed_work(sock->wq,
+                                               &host->abort_handler,
+                                               host->timeout_jiffies);
+                                       host->state = SCMD;
+                                       goto done;
+                               } else {
+                                       host->req->cmd->error = error_code;
+                               }
+                       } else {
+                               host->req->cmd->error = error_code;
+                       }
+                       host->state = READY;
+               }
+
+               if (host_status & TIFM_MMCSD_CB)
+                       host->flags |= CARD_BUSY;
+               if ((host_status & TIFM_MMCSD_EOFB) &&
+                               (host->flags & CARD_BUSY)) {
+                       host->written_blocks++;
+                       host->flags &= ~CARD_BUSY;
+               }
+        }
+
+       if (host->req)
+               tifm_sd_process_cmd(sock, host, host_status);
+done:
+       dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n",
+                       host_status, fifo_status);
+       spin_unlock(&sock->lock);
+       return sock_irq_status;
+}
+
+static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
+{
+       struct tifm_dev *sock = card->dev;
+       unsigned int dest_cnt;
+
+       /* DMA style IO */
+
+       writel(TIFM_FIFO_INT_SETALL,
+               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+       writel(long_log2(cmd->data->blksz) - 2,
+                       sock->addr + SOCK_FIFO_PAGE_SIZE);
+       writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
+       writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
+
+       dest_cnt = (cmd->data->blocks) << 8;
+
+       writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS);
+
+       writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+       writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
+
+       if (cmd->data->flags & MMC_DATA_WRITE) {
+               writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+               writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN,
+                       sock->addr + SOCK_DMA_CONTROL);
+       } else {
+               writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+               writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL);
+       }
+}
+
+static void tifm_sd_set_data_timeout(struct tifm_sd *host,
+                                       struct mmc_data *data)
+{
+       struct tifm_dev *sock = host->dev;
+       unsigned int data_timeout = data->timeout_clks;
+
+       if (fixed_timeout)
+               return;
+
+       data_timeout += data->timeout_ns /
+                       ((1000000000 / host->clk_freq) * host->clk_div);
+       data_timeout *= 10; // call it fudge factor for now
+
+       if (data_timeout < 0xffff) {
+               writel((~TIFM_MMCSD_DPE) &
+                               readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
+                      sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
+               writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
+       } else {
+               writel(TIFM_MMCSD_DPE |
+                               readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
+                       sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
+               data_timeout = (data_timeout >> 10) + 1;
+               if(data_timeout > 0xffff)
+                       data_timeout = 0;       /* set to unlimited */
+               writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
+       }
+}
+
+static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+       struct tifm_sd *host = mmc_priv(mmc);
+       struct tifm_dev *sock = host->dev;
+       unsigned long flags;
+       int sg_count = 0;
+       struct mmc_data *r_data = mrq->cmd->data;
+
+       spin_lock_irqsave(&sock->lock, flags);
+       if (host->flags & EJECT) {
+               spin_unlock_irqrestore(&sock->lock, flags);
+               goto err_out;
+       }
+
+       if (host->req) {
+               printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
+               spin_unlock_irqrestore(&sock->lock, flags);
+               goto err_out;
+       }
+
+       if (r_data) {
+               tifm_sd_set_data_timeout(host, r_data);
+
+               sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len,
+                                      mrq->cmd->flags & MMC_DATA_WRITE
+                                      ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+               if (sg_count != 1) {
+                       printk(KERN_ERR DRIVER_NAME
+                               ": scatterlist map failed\n");
+                       spin_unlock_irqrestore(&sock->lock, flags);
+                       goto err_out;
+               }
+
+               host->written_blocks = 0;
+               host->flags &= ~CARD_BUSY;
+               tifm_sd_prepare_data(host, mrq->cmd);
+       }
+
+       host->req = mrq;
+       host->state = CMD;
+       queue_delayed_work(sock->wq, &host->abort_handler,
+                               host->timeout_jiffies);
+       writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
+               sock->addr + SOCK_CONTROL);
+       tifm_sd_exec(host, mrq->cmd);
+       spin_unlock_irqrestore(&sock->lock, flags);
+       return;
+
+err_out:
+       if (sg_count > 0)
+               tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
+                             (r_data->flags & MMC_DATA_WRITE)
+                             ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+
+       mrq->cmd->error = MMC_ERR_TIMEOUT;
+       mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_end_cmd(void *data)
+{
+       struct tifm_sd *host = data;
+       struct tifm_dev *sock = host->dev;
+       struct mmc_host *mmc = tifm_get_drvdata(sock);
+       struct mmc_request *mrq;
+       struct mmc_data *r_data = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+
+       mrq = host->req;
+       host->req = 0;
+       host->state = IDLE;
+
+       if (!mrq) {
+               printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
+               spin_unlock_irqrestore(&sock->lock, flags);
+               return;
+       }
+
+       r_data = mrq->cmd->data;
+       if (r_data) {
+               if (r_data->flags & MMC_DATA_WRITE) {
+                       r_data->bytes_xfered = host->written_blocks *
+                                               r_data->blksz;
+               } else {
+                       r_data->bytes_xfered = r_data->blocks -
+                               readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
+                       r_data->bytes_xfered *= r_data->blksz;
+                       r_data->bytes_xfered += r_data->blksz -
+                               readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
+               }
+               tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
+                             (r_data->flags & MMC_DATA_WRITE)
+                             ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+       }
+
+       writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
+                       sock->addr + SOCK_CONTROL);
+
+       spin_unlock_irqrestore(&sock->lock, flags);
+       mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+       struct tifm_sd *host = mmc_priv(mmc);
+       struct tifm_dev *sock = host->dev;
+       unsigned long flags;
+       struct mmc_data *r_data = mrq->cmd->data;
+       char *t_buffer = 0;
+
+       if (r_data) {
+               t_buffer = kmap(r_data->sg->page);
+               if (!t_buffer) {
+                       printk(KERN_ERR DRIVER_NAME ": kmap failed\n");
+                       goto err_out;
+               }
+       }
+
+       spin_lock_irqsave(&sock->lock, flags);
+       if (host->flags & EJECT) {
+               spin_unlock_irqrestore(&sock->lock, flags);
+               goto err_out;
+       }
+
+       if (host->req) {
+               printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
+               spin_unlock_irqrestore(&sock->lock, flags);
+               goto err_out;
+       }
+
+       if (r_data) {
+               tifm_sd_set_data_timeout(host, r_data);
+
+               host->buffer = t_buffer + r_data->sg->offset;
+               host->buffer_size = mrq->cmd->data->blocks *
+                                       mrq->cmd->data->blksz;
+
+               writel(TIFM_MMCSD_BUFINT |
+                               readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
+                      sock->addr + SOCK_MMCSD_INT_ENABLE);
+               writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) |
+                               (TIFM_MMCSD_FIFO_SIZE - 1),
+                      sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+
+               host->written_blocks = 0;
+               host->flags &= ~CARD_BUSY;
+               host->buffer_pos = 0;
+               writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+               writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
+       }
+
+       host->req = mrq;
+       host->state = CMD;
+       queue_delayed_work(sock->wq, &host->abort_handler,
+                               host->timeout_jiffies);
+       writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
+               sock->addr + SOCK_CONTROL);
+       tifm_sd_exec(host, mrq->cmd);
+       spin_unlock_irqrestore(&sock->lock, flags);
+       return;
+
+err_out:
+       if (t_buffer)
+               kunmap(r_data->sg->page);
+
+       mrq->cmd->error = MMC_ERR_TIMEOUT;
+       mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_end_cmd_nodma(void *data)
+{
+       struct tifm_sd *host = (struct tifm_sd*)data;
+       struct tifm_dev *sock = host->dev;
+       struct mmc_host *mmc = tifm_get_drvdata(sock);
+       struct mmc_request *mrq;
+       struct mmc_data *r_data = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+
+       mrq = host->req;
+       host->req = 0;
+       host->state = IDLE;
+
+       if (!mrq) {
+               printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
+               spin_unlock_irqrestore(&sock->lock, flags);
+               return;
+       }
+
+       r_data = mrq->cmd->data;
+       if (r_data) {
+               writel((~TIFM_MMCSD_BUFINT) &
+                       readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
+                       sock->addr + SOCK_MMCSD_INT_ENABLE);
+
+               if (r_data->flags & MMC_DATA_WRITE) {
+                       r_data->bytes_xfered = host->written_blocks *
+                                               r_data->blksz;
+               } else {
+                       r_data->bytes_xfered = r_data->blocks -
+                               readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
+                       r_data->bytes_xfered *= r_data->blksz;
+                       r_data->bytes_xfered += r_data->blksz -
+                               readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
+               }
+               host->buffer = 0;
+               host->buffer_pos = 0;
+               host->buffer_size = 0;
+       }
+
+       writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
+                       sock->addr + SOCK_CONTROL);
+
+       spin_unlock_irqrestore(&sock->lock, flags);
+
+        if (r_data)
+               kunmap(r_data->sg->page);
+
+       mmc_request_done(mmc, mrq);
+}
+
+static void tifm_sd_abort(void *data)
+{
+       printk(KERN_ERR DRIVER_NAME
+               ": card failed to respond for a long period of time");
+       tifm_eject(((struct tifm_sd*)data)->dev);
+}
+
+static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct tifm_sd *host = mmc_priv(mmc);
+       struct tifm_dev *sock = host->dev;
+       unsigned int clk_div1, clk_div2;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+
+       dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width,
+               ios->power_mode);
+       if (ios->bus_width == MMC_BUS_WIDTH_4) {
+               writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
+                      sock->addr + SOCK_MMCSD_CONFIG);
+       } else {
+               writel((~TIFM_MMCSD_4BBUS) &
+                               readl(sock->addr + SOCK_MMCSD_CONFIG),
+                       sock->addr + SOCK_MMCSD_CONFIG);
+       }
+
+       if (ios->clock) {
+               clk_div1 = 20000000 / ios->clock;
+               if (!clk_div1)
+                       clk_div1 = 1;
+
+               clk_div2 = 24000000 / ios->clock;
+               if (!clk_div2)
+                       clk_div2 = 1;
+
+               if ((20000000 / clk_div1) > ios->clock)
+                       clk_div1++;
+               if ((24000000 / clk_div2) > ios->clock)
+                       clk_div2++;
+               if ((20000000 / clk_div1) > (24000000 / clk_div2)) {
+                       host->clk_freq = 20000000;
+                       host->clk_div = clk_div1;
+                       writel((~TIFM_CTRL_FAST_CLK) &
+                                       readl(sock->addr + SOCK_CONTROL),
+                               sock->addr + SOCK_CONTROL);
+               } else {
+                       host->clk_freq = 24000000;
+                       host->clk_div = clk_div2;
+                       writel(TIFM_CTRL_FAST_CLK |
+                                       readl(sock->addr + SOCK_CONTROL),
+                               sock->addr + SOCK_CONTROL);
+               }
+       } else {
+               host->clk_div = 0;
+       }
+       host->clk_div &= TIFM_MMCSD_CLKMASK;
+       writel(host->clk_div | ((~TIFM_MMCSD_CLKMASK) &
+                       readl(sock->addr + SOCK_MMCSD_CONFIG)),
+               sock->addr + SOCK_MMCSD_CONFIG);
+
+       if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+               host->flags |= OPENDRAIN;
+       else
+               host->flags &= ~OPENDRAIN;
+
+       /* chip_select : maybe later */
+       //vdd
+       //power is set before probe / after remove
+       //I believe, power_off when already marked for eject is sufficient to
+       // allow removal.
+       if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) {
+               host->flags |= EJECT_DONE;
+               wake_up_all(&host->can_eject);
+       }
+
+       spin_unlock_irqrestore(&sock->lock, flags);
+}
+
+static int tifm_sd_ro(struct mmc_host *mmc)
+{
+       int rc;
+       struct tifm_sd *host = mmc_priv(mmc);
+       struct tifm_dev *sock = host->dev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+
+       host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE));
+       rc = (host->flags & CARD_RO) ? 1 : 0;
+
+       spin_unlock_irqrestore(&sock->lock, flags);
+       return rc;
+}
+
+static struct mmc_host_ops tifm_sd_ops = {
+       .request = tifm_sd_request,
+       .set_ios = tifm_sd_ios,
+       .get_ro  = tifm_sd_ro
+};
+
+static void tifm_sd_register_host(void *data)
+{
+       struct tifm_sd *host = (struct tifm_sd*)data;
+       struct tifm_dev *sock = host->dev;
+       struct mmc_host *mmc = tifm_get_drvdata(sock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+       host->flags |= HOST_REG;
+       PREPARE_WORK(&host->cmd_handler,
+                       no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
+                       data);
+       spin_unlock_irqrestore(&sock->lock, flags);
+       dev_dbg(&sock->dev, "adding host\n");
+       mmc_add_host(mmc);
+}
+
+static int tifm_sd_probe(struct tifm_dev *sock)
+{
+       struct mmc_host *mmc;
+       struct tifm_sd *host;
+       int rc = -EIO;
+
+       if (!(TIFM_SOCK_STATE_OCCUPIED &
+                       readl(sock->addr + SOCK_PRESENT_STATE))) {
+               printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n");
+               return rc;
+       }
+
+       mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev);
+       if (!mmc)
+               return -ENOMEM;
+
+       host = mmc_priv(mmc);
+       host->dev = sock;
+       host->clk_div = 61;
+       init_waitqueue_head(&host->can_eject);
+       INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host);
+       INIT_WORK(&host->abort_handler, tifm_sd_abort, host);
+
+       tifm_set_drvdata(sock, mmc);
+       sock->signal_irq = tifm_sd_signal_irq;
+
+       host->clk_freq = 20000000;
+       host->timeout_jiffies = msecs_to_jiffies(1000);
+
+       tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request;
+       mmc->ops = &tifm_sd_ops;
+       mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+       mmc->caps = MMC_CAP_4_BIT_DATA;
+       mmc->f_min = 20000000 / 60;
+       mmc->f_max = 24000000;
+       mmc->max_hw_segs = 1;
+       mmc->max_phys_segs = 1;
+       mmc->max_sectors = 127;
+       mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length
+
+       writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
+       writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
+       writel(host->clk_div | TIFM_MMCSD_POWER,
+                       sock->addr + SOCK_MMCSD_CONFIG);
+
+       for (rc = 0; rc < 50; rc++) {
+               /* Wait for reset ack */
+               if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
+                       rc = 0;
+                       break;
+               }
+               msleep(10);
+        }
+
+       if (rc) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": card not ready - probe failed\n");
+               mmc_free_host(mmc);
+               return -ENODEV;
+       }
+
+       writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
+       writel(host->clk_div | TIFM_MMCSD_POWER,
+                       sock->addr + SOCK_MMCSD_CONFIG);
+       writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
+       writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK,
+                       sock->addr + SOCK_MMCSD_INT_ENABLE);
+
+       writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); // command timeout 64 clocks for now
+       writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
+       writel(host->clk_div | TIFM_MMCSD_POWER,
+                       sock->addr + SOCK_MMCSD_CONFIG);
+
+       queue_delayed_work(sock->wq, &host->abort_handler,
+                       host->timeout_jiffies);
+
+       return 0;
+}
+
+static int tifm_sd_host_is_down(struct tifm_dev *sock)
+{
+       struct mmc_host *mmc = tifm_get_drvdata(sock);
+       struct tifm_sd *host = mmc_priv(mmc);
+       unsigned long flags;
+       int rc = 0;
+
+       spin_lock_irqsave(&sock->lock, flags);
+       rc = (host->flags & EJECT_DONE);
+       spin_unlock_irqrestore(&sock->lock, flags);
+       return rc;
+}
+
+static void tifm_sd_remove(struct tifm_dev *sock)
+{
+       struct mmc_host *mmc = tifm_get_drvdata(sock);
+       struct tifm_sd *host = mmc_priv(mmc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sock->lock, flags);
+       host->flags |= EJECT;
+       if (host->req)
+               queue_work(sock->wq, &host->cmd_handler);
+       spin_unlock_irqrestore(&sock->lock, flags);
+       wait_event_timeout(host->can_eject, tifm_sd_host_is_down(sock),
+                               host->timeout_jiffies);
+
+       if (host->flags & HOST_REG)
+               mmc_remove_host(mmc);
+
+       /* The meaning of the bit majority in this constant is unknown. */
+       writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
+               sock->addr + SOCK_CONTROL);
+       writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
+       writel(TIFM_FIFO_INT_SETALL,
+               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
+       writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
+
+       tifm_set_drvdata(sock, 0);
+       mmc_free_host(mmc);
+}
+
+static tifm_media_id tifm_sd_id_tbl[] = {
+       FM_SD, 0
+};
+
+static struct tifm_driver tifm_sd_driver = {
+       .driver = {
+               .name  = DRIVER_NAME,
+               .owner = THIS_MODULE
+       },
+       .id_table = tifm_sd_id_tbl,
+       .probe    = tifm_sd_probe,
+       .remove   = tifm_sd_remove
+};
+
+static int __init tifm_sd_init(void)
+{
+       return tifm_register_driver(&tifm_sd_driver);
+}
+
+static void __exit tifm_sd_exit(void)
+{
+       tifm_unregister_driver(&tifm_sd_driver);
+}
+
+MODULE_AUTHOR("Alex Dubov");
+MODULE_DESCRIPTION("TI FlashMedia SD driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl);
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tifm_sd_init);
+module_exit(tifm_sd_exit);
index 6d8f30deb8689e14a5a7d385bc45abc888b8777e..72e6d73beb40d169ca324c36d97735fd34b248e3 100644 (file)
@@ -270,7 +270,7 @@ config MTD_JEDEC
        tristate "JEDEC device support"
        depends on MTD && MTD_OBSOLETE_CHIPS && BROKEN
        help
-         Enable older older JEDEC flash interface devices for self
+         Enable older JEDEC flash interface devices for self
          programming flash.  It is commonly used in older AMD chips.  It is
          only called JEDEC because the JEDEC association
          <http://www.jedec.org/> distributes the identification codes for the
index 51f962dd7e31c42054850e3344326f69acbf2752..e074bb6787d21fb0a9c75447b00d01d8348d78eb 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/drivers/mtd/maps/bast_flash.c
+/* linux/drivers/mtd/maps/bast-flash.c
  *
  * Copyright (c) 2004-2005 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index a43c49905cac812d2d6790ac0ca1666141d7a880..e0558b0b2fe65946ecfd00b3a05f57f79624633d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * drivers/mtd/maps/svme182.c
+ * drivers/mtd/maps/dmv182.c
  *
  * Flash map driver for the Dy4 SVME182 board
  *
index c99302ed3823250a7d31c0de37188a914fd93b15..1831340e5f5141e87777d0ef4c54b66ae7e6030c 100644 (file)
@@ -21,7 +21,7 @@ config MTD_NAND_VERIFY_WRITE
          NAND flash device internally checks only bits transitioning
          from 1 to 0. There is a rare possibility that even though the
          device thinks the write was successful, a bit could have been
-         flipped accidentaly due to device wear or something else.
+         flipped accidentally due to device wear or something else.
 
 config MTD_NAND_ECC_SMC
        bool "NAND ECC Smart Media byte order"
index 465961b8bcd14319e02be8c0adf8d8db41862288..373bddce8f1c661354c9f5b568db564f70ab142a 100644 (file)
@@ -21,7 +21,7 @@ config MTD_ONENAND_VERIFY_WRITE
          OneNAND flash device internally checks only bits transitioning
          from 1 to 0. There is a rare possibility that even though the
          device thinks the write was successful, a bit could have been
-         flipped accidentaly due to device wear or something else.
+         flipped accidentally due to device wear or something else.
 
 config MTD_ONENAND_GENERIC
        tristate "OneNAND Flash device via platform device driver"
index ff8a8c0a26d5ce33c227ab5b75cabc63472c3649..ab92cc794c64d85363b98d1bf3aa76585c68ccc8 100644 (file)
@@ -2115,7 +2115,7 @@ config SKY2
        depends on PCI && EXPERIMENTAL
        select CRC32
        ---help---
-         This driver supports Gigabit Ethernet adapters based on the the
+         This driver supports Gigabit Ethernet adapters based on the
          Marvell Yukon 2 chipset:
          Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
          88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
index 6a49ac7f6d466735e4a4f5f19db36afa910acb8a..483009fe6ec2545010f9bb95fec9ac0ce9d981d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/net/am79c961.h
+ * linux/drivers/net/arm/am79c961a.h
  *
  * 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
index 5761389495d008c8cf750aad0fc0dc3d7ed379c7..6c7dccc84bf59b0ca5a53a5b3d0d6044e4eca3f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_emac/ibm_ocp_debug.h
+ * drivers/net/ibm_emac/ibm_emac_debug.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
index 94abde55e2e9fde1a930de8fe748568503b9aa59..117ea486c2ca9b97c8419f4bca4b609fe164a79b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_emac/ibm_emac_rgmii.c
+ * drivers/net/ibm_emac/ibm_emac_rgmii.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
index 7d3e270c4f4539888d9caf0162688eaeb643ea80..3b2f00b9b7bd89a717734e16fa065a1e6991cd81 100644 (file)
@@ -224,8 +224,7 @@ static void __devexit tms_pci_detach (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
 
-       if (!dev)
-               BUG();
+       BUG_ON(!dev);
        unregister_netdev(dev);
        release_region(dev->base_addr, TMS_PCI_IO_EXTENT);
        free_irq(dev->irq, dev);
index bd4a68c85a4717e00cb354c7c43125bd325d88af..ece3d9c2dc617737afecf77180273da64328b14e 100644 (file)
@@ -301,7 +301,7 @@ config HERMES
        tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
        depends on NET_RADIO && (PPC_PMAC || PCI || PCMCIA)
        ---help---
-         A driver for 802.11b wireless cards based based on the "Hermes" or
+         A driver for 802.11b wireless cards based on the "Hermes" or
          Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
          majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
          - except for the Cisco/Aironet cards.  Cards supported include the
index 4a9f025a6b58026ba208d4a3a695b9d7b9ffa608..2eb3577a88c50f07d0190a6d45efcf2aed345926 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/parisc/kernel/power.c
+ * linux/drivers/parisc/power.c
  * HP PARISC soft power switch support driver
  *
  * Copyright (c) 2001-2005 Helge Deller <deller@gmx.de>
index fd41e28101eaa4b305230fccdaad77392847ab15..83ee095ec6e277573acda23eae20945f4d36fcd4 100644 (file)
@@ -30,7 +30,7 @@
 #undef DEBUG
 
 #ifdef DEBUG
-#define DPRINTK(stuff...) printk (stuff)
+#define DPRINTK(stuff...) printk(stuff)
 #else
 #define DPRINTK(stuff...)
 #endif
@@ -46,16 +46,16 @@ static DEFINE_SPINLOCK(topology_lock);
 static int numdevs = 0;
 
 /* Forward-declaration of lower-level functions. */
-static int mux_present (struct parport *port);
-static int num_mux_ports (struct parport *port);
-static int select_port (struct parport *port);
-static int assign_addrs (struct parport *port);
+static int mux_present(struct parport *port);
+static int num_mux_ports(struct parport *port);
+static int select_port(struct parport *port);
+static int assign_addrs(struct parport *port);
 
 /* Add a device to the discovered topology. */
-static void add_dev (int devnum, struct parport *port, int daisy)
+static void add_dev(int devnum, struct parport *port, int daisy)
 {
        struct daisydev *newdev, **p;
-       newdev = kmalloc (sizeof (struct daisydev), GFP_KERNEL);
+       newdev = kmalloc(sizeof(struct daisydev), GFP_KERNEL);
        if (newdev) {
                newdev->port = port;
                newdev->daisy = daisy;
@@ -70,9 +70,9 @@ static void add_dev (int devnum, struct parport *port, int daisy)
 }
 
 /* Clone a parport (actually, make an alias). */
-static struct parport *clone_parport (struct parport *real, int muxport)
+static struct parport *clone_parport(struct parport *real, int muxport)
 {
-       struct parport *extra = parport_register_port (real->base,
+       struct parport *extra = parport_register_port(real->base,
                                                       real->irq,
                                                       real->dma,
                                                       real->ops);
@@ -88,7 +88,7 @@ static struct parport *clone_parport (struct parport *real, int muxport)
 
 /* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
  * Return value is number of devices actually detected. */
-int parport_daisy_init (struct parport *port)
+int parport_daisy_init(struct parport *port)
 {
        int detected = 0;
        char *deviceid;
@@ -103,26 +103,26 @@ again:
 
        /* If mux present on normal port, need to create new
         * parports for each extra port. */
-       if (port->muxport < 0 && mux_present (port) &&
+       if (port->muxport < 0 && mux_present(port) &&
            /* don't be fooled: a mux must have 2 or 4 ports. */
-           ((num_ports = num_mux_ports (port)) == 2 || num_ports == 4)) {
+           ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) {
                /* Leave original as port zero. */
                port->muxport = 0;
-               printk (KERN_INFO
+               printk(KERN_INFO
                        "%s: 1st (default) port of %d-way multiplexor\n",
                        port->name, num_ports);
                for (i = 1; i < num_ports; i++) {
                        /* Clone the port. */
-                       struct parport *extra = clone_parport (port, i);
+                       struct parport *extra = clone_parport(port, i);
                        if (!extra) {
-                               if (signal_pending (current))
+                               if (signal_pending(current))
                                        break;
 
-                               schedule ();
+                               schedule();
                                continue;
                        }
 
-                       printk (KERN_INFO
+                       printk(KERN_INFO
                                "%s: %d%s port of %d-way multiplexor on %s\n",
                                extra->name, i + 1, th[i + 1], num_ports,
                                port->name);
@@ -135,34 +135,34 @@ again:
        }
 
        if (port->muxport >= 0)
-               select_port (port);
+               select_port(port);
 
-       parport_daisy_deselect_all (port);
-       detected += assign_addrs (port);
+       parport_daisy_deselect_all(port);
+       detected += assign_addrs(port);
 
        /* Count the potential legacy device at the end. */
-       add_dev (numdevs++, port, -1);
+       add_dev(numdevs++, port, -1);
 
        /* Find out the legacy device's IEEE 1284 device ID. */
-       deviceid = kmalloc (1024, GFP_KERNEL);
+       deviceid = kmalloc(1024, GFP_KERNEL);
        if (deviceid) {
-               if (parport_device_id (numdevs - 1, deviceid, 1024) > 2)
+               if (parport_device_id(numdevs - 1, deviceid, 1024) > 2)
                        detected++;
 
-               kfree (deviceid);
+               kfree(deviceid);
        }
 
        if (!detected && !last_try) {
                /* No devices were detected.  Perhaps they are in some
                    funny state; let's try to reset them and see if
                    they wake up. */
-               parport_daisy_fini (port);
-               parport_write_control (port, PARPORT_CONTROL_SELECT);
-               udelay (50);
-               parport_write_control (port,
+               parport_daisy_fini(port);
+               parport_write_control(port, PARPORT_CONTROL_SELECT);
+               udelay(50);
+               parport_write_control(port,
                                       PARPORT_CONTROL_SELECT |
                                       PARPORT_CONTROL_INIT);
-               udelay (50);
+               udelay(50);
                last_try = 1;
                goto again;
        }
@@ -171,7 +171,7 @@ again:
 }
 
 /* Forget about devices on a physical port. */
-void parport_daisy_fini (struct parport *port)
+void parport_daisy_fini(struct parport *port)
 {
        struct daisydev **p;
 
@@ -214,7 +214,7 @@ void parport_daisy_fini (struct parport *port)
  *     for parport_register_device().
  **/
 
-struct pardevice *parport_open (int devnum, const char *name,
+struct pardevice *parport_open(int devnum, const char *name,
                                int (*pf) (void *), void (*kf) (void *),
                                void (*irqf) (int, void *, struct pt_regs *),
                                int flags, void *handle)
@@ -237,7 +237,7 @@ struct pardevice *parport_open (int devnum, const char *name,
        port = parport_get_port(p->port);
        spin_unlock(&topology_lock);
 
-       dev = parport_register_device (port, name, pf, kf,
+       dev = parport_register_device(port, name, pf, kf,
                                       irqf, flags, handle);
        parport_put_port(port);
        if (!dev)
@@ -248,13 +248,13 @@ struct pardevice *parport_open (int devnum, const char *name,
        /* Check that there really is a device to select. */
        if (daisy >= 0) {
                int selected;
-               parport_claim_or_block (dev);
+               parport_claim_or_block(dev);
                selected = port->daisy;
-               parport_release (dev);
+               parport_release(dev);
 
                if (selected != daisy) {
                        /* No corresponding device. */
-                       parport_unregister_device (dev);
+                       parport_unregister_device(dev);
                        return NULL;
                }
        }
@@ -270,9 +270,9 @@ struct pardevice *parport_open (int devnum, const char *name,
  *     parport_register_device().
  **/
 
-void parport_close (struct pardevice *dev)
+void parport_close(struct pardevice *dev)
 {
-       parport_unregister_device (dev);
+       parport_unregister_device(dev);
 }
 
 /**
@@ -287,7 +287,7 @@ void parport_close (struct pardevice *dev)
  *     exists.
  **/
 
-int parport_device_num (int parport, int mux, int daisy)
+int parport_device_num(int parport, int mux, int daisy)
 {
        int res = -ENXIO;
        struct daisydev *dev;
@@ -305,16 +305,16 @@ int parport_device_num (int parport, int mux, int daisy)
 }
 
 /* Send a daisy-chain-style CPP command packet. */
-static int cpp_daisy (struct parport *port, int cmd)
+static int cpp_daisy(struct parport *port, int cmd)
 {
        unsigned char s;
 
-       parport_data_forward (port);
-       parport_write_data (port, 0xaa); udelay (2);
-       parport_write_data (port, 0x55); udelay (2);
-       parport_write_data (port, 0x00); udelay (2);
-       parport_write_data (port, 0xff); udelay (2);
-       s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+       parport_data_forward(port);
+       parport_write_data(port, 0xaa); udelay(2);
+       parport_write_data(port, 0x55); udelay(2);
+       parport_write_data(port, 0x00); udelay(2);
+       parport_write_data(port, 0xff); udelay(2);
+       s = parport_read_status(port) & (PARPORT_STATUS_BUSY
                                          | PARPORT_STATUS_PAPEROUT
                                          | PARPORT_STATUS_SELECT
                                          | PARPORT_STATUS_ERROR);
@@ -322,54 +322,54 @@ static int cpp_daisy (struct parport *port, int cmd)
                  | PARPORT_STATUS_PAPEROUT
                  | PARPORT_STATUS_SELECT
                  | PARPORT_STATUS_ERROR)) {
-               DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
+               DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
                         port->name, s);
                return -ENXIO;
        }
 
-       parport_write_data (port, 0x87); udelay (2);
-       s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+       parport_write_data(port, 0x87); udelay(2);
+       s = parport_read_status(port) & (PARPORT_STATUS_BUSY
                                          | PARPORT_STATUS_PAPEROUT
                                          | PARPORT_STATUS_SELECT
                                          | PARPORT_STATUS_ERROR);
        if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
-               DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
+               DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
                         port->name, s);
                return -ENXIO;
        }
 
-       parport_write_data (port, 0x78); udelay (2);
-       parport_write_data (port, cmd); udelay (2);
-       parport_frob_control (port,
+       parport_write_data(port, 0x78); udelay(2);
+       parport_write_data(port, cmd); udelay(2);
+       parport_frob_control(port,
                              PARPORT_CONTROL_STROBE,
                              PARPORT_CONTROL_STROBE);
-       udelay (1);
-       s = parport_read_status (port);
-       parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
-       udelay (1);
-       parport_write_data (port, 0xff); udelay (2);
+       udelay(1);
+       s = parport_read_status(port);
+       parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
+       udelay(1);
+       parport_write_data(port, 0xff); udelay(2);
 
        return s;
 }
 
 /* Send a mux-style CPP command packet. */
-static int cpp_mux (struct parport *port, int cmd)
+static int cpp_mux(struct parport *port, int cmd)
 {
        unsigned char s;
        int rc;
 
-       parport_data_forward (port);
-       parport_write_data (port, 0xaa); udelay (2);
-       parport_write_data (port, 0x55); udelay (2);
-       parport_write_data (port, 0xf0); udelay (2);
-       parport_write_data (port, 0x0f); udelay (2);
-       parport_write_data (port, 0x52); udelay (2);
-       parport_write_data (port, 0xad); udelay (2);
-       parport_write_data (port, cmd); udelay (2);
+       parport_data_forward(port);
+       parport_write_data(port, 0xaa); udelay(2);
+       parport_write_data(port, 0x55); udelay(2);
+       parport_write_data(port, 0xf0); udelay(2);
+       parport_write_data(port, 0x0f); udelay(2);
+       parport_write_data(port, 0x52); udelay(2);
+       parport_write_data(port, 0xad); udelay(2);
+       parport_write_data(port, cmd); udelay(2);
 
-       s = parport_read_status (port);
+       s = parport_read_status(port);
        if (!(s & PARPORT_STATUS_ACK)) {
-               DPRINTK (KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
+               DPRINTK(KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
                         port->name, cmd, s);
                return -EIO;
        }
@@ -382,12 +382,12 @@ static int cpp_mux (struct parport *port, int cmd)
        return rc;
 }
 
-void parport_daisy_deselect_all (struct parport *port)
+void parport_daisy_deselect_all(struct parport *port)
 {
-       cpp_daisy (port, 0x30);
+       cpp_daisy(port, 0x30);
 }
 
-int parport_daisy_select (struct parport *port, int daisy, int mode)
+int parport_daisy_select(struct parport *port, int daisy, int mode)
 {
        switch (mode)
        {
@@ -395,14 +395,14 @@ int parport_daisy_select (struct parport *port, int daisy, int mode)
                case IEEE1284_MODE_EPP:
                case IEEE1284_MODE_EPPSL:
                case IEEE1284_MODE_EPPSWE:
-                       return !(cpp_daisy (port, 0x20 + daisy) &
+                       return !(cpp_daisy(port, 0x20 + daisy) &
                                 PARPORT_STATUS_ERROR);
 
                // For these modes we should switch to ECP mode:
                case IEEE1284_MODE_ECP:
                case IEEE1284_MODE_ECPRLE:
                case IEEE1284_MODE_ECPSWE: 
-                       return !(cpp_daisy (port, 0xd0 + daisy) &
+                       return !(cpp_daisy(port, 0xd0 + daisy) &
                                 PARPORT_STATUS_ERROR);
 
                // Nothing was told for BECP in Daisy chain specification.
@@ -413,28 +413,28 @@ int parport_daisy_select (struct parport *port, int daisy, int mode)
                case IEEE1284_MODE_BYTE:
                case IEEE1284_MODE_COMPAT:
                default:
-                       return !(cpp_daisy (port, 0xe0 + daisy) &
+                       return !(cpp_daisy(port, 0xe0 + daisy) &
                                 PARPORT_STATUS_ERROR);
        }
 }
 
-static int mux_present (struct parport *port)
+static int mux_present(struct parport *port)
 {
-       return cpp_mux (port, 0x51) == 3;
+       return cpp_mux(port, 0x51) == 3;
 }
 
-static int num_mux_ports (struct parport *port)
+static int num_mux_ports(struct parport *port)
 {
-       return cpp_mux (port, 0x58);
+       return cpp_mux(port, 0x58);
 }
 
-static int select_port (struct parport *port)
+static int select_port(struct parport *port)
 {
        int muxport = port->muxport;
-       return cpp_mux (port, 0x60 + muxport) == muxport;
+       return cpp_mux(port, 0x60 + muxport) == muxport;
 }
 
-static int assign_addrs (struct parport *port)
+static int assign_addrs(struct parport *port)
 {
        unsigned char s;
        unsigned char daisy;
@@ -442,12 +442,12 @@ static int assign_addrs (struct parport *port)
        int detected;
        char *deviceid;
 
-       parport_data_forward (port);
-       parport_write_data (port, 0xaa); udelay (2);
-       parport_write_data (port, 0x55); udelay (2);
-       parport_write_data (port, 0x00); udelay (2);
-       parport_write_data (port, 0xff); udelay (2);
-       s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+       parport_data_forward(port);
+       parport_write_data(port, 0xaa); udelay(2);
+       parport_write_data(port, 0x55); udelay(2);
+       parport_write_data(port, 0x00); udelay(2);
+       parport_write_data(port, 0xff); udelay(2);
+       s = parport_read_status(port) & (PARPORT_STATUS_BUSY
                                          | PARPORT_STATUS_PAPEROUT
                                          | PARPORT_STATUS_SELECT
                                          | PARPORT_STATUS_ERROR);
@@ -455,40 +455,40 @@ static int assign_addrs (struct parport *port)
                  | PARPORT_STATUS_PAPEROUT
                  | PARPORT_STATUS_SELECT
                  | PARPORT_STATUS_ERROR)) {
-               DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
+               DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
                         port->name, s);
                return 0;
        }
 
-       parport_write_data (port, 0x87); udelay (2);
-       s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+       parport_write_data(port, 0x87); udelay(2);
+       s = parport_read_status(port) & (PARPORT_STATUS_BUSY
                                          | PARPORT_STATUS_PAPEROUT
                                          | PARPORT_STATUS_SELECT
                                          | PARPORT_STATUS_ERROR);
        if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
-               DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
+               DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
                         port->name, s);
                return 0;
        }
 
-       parport_write_data (port, 0x78); udelay (2);
-       s = parport_read_status (port);
+       parport_write_data(port, 0x78); udelay(2);
+       s = parport_read_status(port);
 
        for (daisy = 0;
             (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT))
                     == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)
                     && daisy < 4;
             ++daisy) {
-               parport_write_data (port, daisy);
-               udelay (2);
-               parport_frob_control (port,
+               parport_write_data(port, daisy);
+               udelay(2);
+               parport_frob_control(port,
                                      PARPORT_CONTROL_STROBE,
                                      PARPORT_CONTROL_STROBE);
-               udelay (1);
-               parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
-               udelay (1);
+               udelay(1);
+               parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
+               udelay(1);
 
-               add_dev (numdevs++, port, daisy);
+               add_dev(numdevs++, port, daisy);
 
                /* See if this device thought it was the last in the
                 * chain. */
@@ -499,21 +499,21 @@ static int assign_addrs (struct parport *port)
                   last_dev from next device or if last_dev does not
                   work status lines from some non-daisy chain
                   device. */
-               s = parport_read_status (port);
+               s = parport_read_status(port);
        }
 
-       parport_write_data (port, 0xff); udelay (2);
+       parport_write_data(port, 0xff); udelay(2);
        detected = numdevs - thisdev;
-       DPRINTK (KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
+       DPRINTK(KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
                 detected);
 
        /* Ask the new devices to introduce themselves. */
-       deviceid = kmalloc (1024, GFP_KERNEL);
+       deviceid = kmalloc(1024, GFP_KERNEL);
        if (!deviceid) return 0;
 
        for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
-               parport_device_id (thisdev, deviceid, 1024);
+               parport_device_id(thisdev, deviceid, 1024);
 
-       kfree (deviceid);
+       kfree(deviceid);
        return detected;
 }
index c27e782e6df999de618dc5a96e6cfd2ec15f6939..30294127a0aa90484b907c235d4424ee773336b0 100644 (file)
@@ -52,3 +52,11 @@ config PCI_DEBUG
 
          When in doubt, say N.
 
+config HT_IRQ
+       bool "Interrupts on hypertransport devices"
+       default y
+       depends on X86_LOCAL_APIC && X86_IO_APIC
+       help
+          This allows native hypertransport devices to use interrupts.
+
+          If unsure say Y.
index f2d152b818f0c162fdf27f66a69b564737518764..e3beb784406f69019511cebf7d8cd33542ccb99c 100644 (file)
@@ -14,6 +14,12 @@ obj-$(CONFIG_HOTPLUG) += hotplug.o
 # Build the PCI Hotplug drivers if we were asked to
 obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
 
+# Build the PCI MSI interrupt support
+obj-$(CONFIG_PCI_MSI) += msi.o
+
+# Build the Hypertransport interrupt support
+obj-$(CONFIG_HT_IRQ) += htirq.o
+
 #
 # Some architectures use the generic PCI setup functions
 #
@@ -27,11 +33,6 @@ obj-$(CONFIG_PPC64) += setup-bus.o
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
 
-msiobj-y := msi.o msi-apic.o
-msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o
-msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o
-obj-$(CONFIG_PCI_MSI) += $(msiobj-y)
-
 #
 # ACPI Related PCI FW Functions
 #
index 8a60f391ffcf4176116d9297f9fbe14c8b42692b..6e780db9454dfbe2e46186e24d9b01df41e25de9 100644 (file)
@@ -157,7 +157,7 @@ config HOTPLUG_PCI_RPA
        tristate "RPA PCI Hotplug driver"
        depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
        help
-         Say Y here if you have a RPA system that supports PCI Hotplug.
+         Say Y here if you have a RPA system that supports PCI Hotplug.
 
          To compile this driver as a module, choose M here: the
          module will be called rpaphp.
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
new file mode 100644 (file)
index 0000000..0e27f24
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * File:       htirq.c
+ * Purpose:    Hypertransport Interrupt Capability
+ *
+ * Copyright (C) 2006 Linux Networx
+ * Copyright (C) Eric Biederman <ebiederman@lnxi.com>
+ */
+
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/htirq.h>
+
+/* Global ht irq lock.
+ *
+ * This is needed to serialize access to the data port in hypertransport
+ * irq capability.
+ *
+ * With multiple simultaneous hypertransport irq devices it might pay
+ * to make this more fine grained.  But start with simple, stupid, and correct.
+ */
+static DEFINE_SPINLOCK(ht_irq_lock);
+
+struct ht_irq_cfg {
+       struct pci_dev *dev;
+       unsigned pos;
+       unsigned idx;
+};
+
+void write_ht_irq_low(unsigned int irq, u32 data)
+{
+       struct ht_irq_cfg *cfg = get_irq_data(irq);
+       unsigned long flags;
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+       pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+void write_ht_irq_high(unsigned int irq, u32 data)
+{
+       struct ht_irq_cfg *cfg = get_irq_data(irq);
+       unsigned long flags;
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
+       pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+u32 read_ht_irq_low(unsigned int irq)
+{
+       struct ht_irq_cfg *cfg = get_irq_data(irq);
+       unsigned long flags;
+       u32 data;
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+       pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+       return data;
+}
+
+u32 read_ht_irq_high(unsigned int irq)
+{
+       struct ht_irq_cfg *cfg = get_irq_data(irq);
+       unsigned long flags;
+       u32 data;
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
+       pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+       return data;
+}
+
+void mask_ht_irq(unsigned int irq)
+{
+       struct ht_irq_cfg *cfg;
+       unsigned long flags;
+       u32 data;
+
+       cfg = get_irq_data(irq);
+
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+       pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+       data |= 1;
+       pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+void unmask_ht_irq(unsigned int irq)
+{
+       struct ht_irq_cfg *cfg;
+       unsigned long flags;
+       u32 data;
+
+       cfg = get_irq_data(irq);
+
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
+       pci_read_config_dword(cfg->dev, cfg->pos + 4, &data);
+       data &= ~1;
+       pci_write_config_dword(cfg->dev, cfg->pos + 4, data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+}
+
+/**
+ * ht_create_irq - create an irq and attach it to a device.
+ * @dev: The hypertransport device to find the irq capability on.
+ * @idx: Which of the possible irqs to attach to.
+ *
+ * ht_create_irq is needs to be called for all hypertransport devices
+ * that generate irqs.
+ *
+ * The irq number of the new irq or a negative error value is returned.
+ */
+int ht_create_irq(struct pci_dev *dev, int idx)
+{
+       struct ht_irq_cfg *cfg;
+       unsigned long flags;
+       u32 data;
+       int max_irq;
+       int pos;
+       int irq;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_HT);
+       while (pos) {
+               u8 subtype;
+               pci_read_config_byte(dev, pos + 3, &subtype);
+               if (subtype == HT_CAPTYPE_IRQ)
+                       break;
+               pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
+       }
+       if (!pos)
+               return -EINVAL;
+
+       /* Verify the idx I want to use is in range */
+       spin_lock_irqsave(&ht_irq_lock, flags);
+       pci_write_config_byte(dev, pos + 2, 1);
+       pci_read_config_dword(dev, pos + 4, &data);
+       spin_unlock_irqrestore(&ht_irq_lock, flags);
+
+       max_irq = (data >> 16) & 0xff;
+       if ( idx > max_irq)
+               return -EINVAL;
+
+       cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+       if (!cfg)
+               return -ENOMEM;
+
+       cfg->dev = dev;
+       cfg->pos = pos;
+       cfg->idx = 0x10 + (idx * 2);
+
+       irq = create_irq();
+       if (irq < 0) {
+               kfree(cfg);
+               return -EBUSY;
+       }
+       set_irq_data(irq, cfg);
+
+       if (arch_setup_ht_irq(irq, dev) < 0) {
+               ht_destroy_irq(irq);
+               return -EBUSY;
+       }
+
+       return irq;
+}
+
+/**
+ * ht_destroy_irq - destroy an irq created with ht_create_irq
+ *
+ * This reverses ht_create_irq removing the specified irq from
+ * existence.  The irq should be free before this happens.
+ */
+void ht_destroy_irq(unsigned int irq)
+{
+       struct ht_irq_cfg *cfg;
+
+       cfg = get_irq_data(irq);
+       set_irq_chip(irq, NULL);
+       set_irq_data(irq, NULL);
+       destroy_irq(irq);
+
+       kfree(cfg);
+}
+
+EXPORT_SYMBOL(ht_create_irq);
+EXPORT_SYMBOL(ht_destroy_irq);
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
deleted file mode 100644 (file)
index 5ed798b..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * MSI hooks for standard x86 apic
- */
-
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <asm/smp.h>
-
-#include "msi.h"
-
-/*
- * Shifts for APIC-based data
- */
-
-#define MSI_DATA_VECTOR_SHIFT          0
-#define            MSI_DATA_VECTOR(v)          (((u8)v) << MSI_DATA_VECTOR_SHIFT)
-
-#define MSI_DATA_DELIVERY_SHIFT                8
-#define     MSI_DATA_DELIVERY_FIXED    (0 << MSI_DATA_DELIVERY_SHIFT)
-#define     MSI_DATA_DELIVERY_LOWPRI   (1 << MSI_DATA_DELIVERY_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT           14
-#define     MSI_DATA_LEVEL_DEASSERT    (0 << MSI_DATA_LEVEL_SHIFT)
-#define     MSI_DATA_LEVEL_ASSERT      (1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT         15
-#define     MSI_DATA_TRIGGER_EDGE      (0 << MSI_DATA_TRIGGER_SHIFT)
-#define     MSI_DATA_TRIGGER_LEVEL     (1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for APIC-based bus address
- */
-
-#define MSI_ADDR_HEADER                        0xfee00000
-
-#define MSI_ADDR_DESTID_MASK           0xfff0000f
-#define     MSI_ADDR_DESTID_CPU(cpu)   ((cpu) << MSI_TARGET_CPU_SHIFT)
-
-#define MSI_ADDR_DESTMODE_SHIFT                2
-#define     MSI_ADDR_DESTMODE_PHYS     (0 << MSI_ADDR_DESTMODE_SHIFT)
-#define            MSI_ADDR_DESTMODE_LOGIC     (1 << MSI_ADDR_DESTMODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT     3
-#define     MSI_ADDR_REDIRECTION_CPU   (0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define     MSI_ADDR_REDIRECTION_LOWPRI        (1 << MSI_ADDR_REDIRECTION_SHIFT)
-
-
-static void
-msi_target_apic(unsigned int vector,
-               unsigned int dest_cpu,
-               u32 *address_hi,        /* in/out */
-               u32 *address_lo)        /* in/out */
-{
-       u32 addr = *address_lo;
-
-       addr &= MSI_ADDR_DESTID_MASK;
-       addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
-
-       *address_lo = addr;
-}
-
-static int
-msi_setup_apic(struct pci_dev *pdev,   /* unused in generic */
-               unsigned int vector,
-               u32 *address_hi,
-               u32 *address_lo,
-               u32 *data)
-{
-       unsigned long   dest_phys_id;
-
-       dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
-
-       *address_hi = 0;
-       *address_lo =   MSI_ADDR_HEADER |
-                       MSI_ADDR_DESTMODE_PHYS |
-                       MSI_ADDR_REDIRECTION_CPU |
-                       MSI_ADDR_DESTID_CPU(dest_phys_id);
-
-       *data = MSI_DATA_TRIGGER_EDGE |
-               MSI_DATA_LEVEL_ASSERT |
-               MSI_DATA_DELIVERY_FIXED |
-               MSI_DATA_VECTOR(vector);
-
-       return 0;
-}
-
-static void
-msi_teardown_apic(unsigned int vector)
-{
-       return;         /* no-op */
-}
-
-/*
- * Generic ops used on most IA archs/platforms.  Set with msi_register()
- */
-
-struct msi_ops msi_apic_ops = {
-       .setup = msi_setup_apic,
-       .teardown = msi_teardown_apic,
-       .target = msi_target_apic,
-};
index 27a057409eca1d53d37ca41d3d2fa4a6844de868..f9fdc54473c4aed27a7f0e865dae74017c352563 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
  */
 
+#include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -14,6 +15,7 @@
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
+#include <linux/msi.h>
 
 #include <asm/errno.h>
 #include <asm/io.h>
@@ -27,23 +29,6 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static kmem_cache_t* msi_cachep;
 
 static int pci_msi_enable = 1;
-static int last_alloc_vector;
-static int nr_released_vectors;
-static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
-static int nr_msix_devices;
-
-#ifndef CONFIG_X86_IO_APIC
-int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
-#endif
-
-static struct msi_ops *msi_ops;
-
-int
-msi_register(struct msi_ops *ops)
-{
-       msi_ops = ops;
-       return 0;
-}
 
 static int msi_cache_init(void)
 {
@@ -55,26 +40,25 @@ static int msi_cache_init(void)
        return 0;
 }
 
-static void msi_set_mask_bit(unsigned int vector, int flag)
+static void msi_set_mask_bit(unsigned int irq, int flag)
 {
        struct msi_desc *entry;
 
-       entry = (struct msi_desc *)msi_desc[vector];
-       if (!entry || !entry->dev || !entry->mask_base)
-               return;
+       entry = msi_desc[irq];
+       BUG_ON(!entry || !entry->dev);
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
-       {
-               int             pos;
-               u32             mask_bits;
-
-               pos = (long)entry->mask_base;
-               pci_read_config_dword(entry->dev, pos, &mask_bits);
-               mask_bits &= ~(1);
-               mask_bits |= flag;
-               pci_write_config_dword(entry->dev, pos, mask_bits);
+               if (entry->msi_attrib.maskbit) {
+                       int             pos;
+                       u32             mask_bits;
+
+                       pos = (long)entry->mask_base;
+                       pci_read_config_dword(entry->dev, pos, &mask_bits);
+                       mask_bits &= ~(1);
+                       mask_bits |= flag;
+                       pci_write_config_dword(entry->dev, pos, mask_bits);
+               }
                break;
-       }
        case PCI_CAP_ID_MSIX:
        {
                int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -83,261 +67,101 @@ static void msi_set_mask_bit(unsigned int vector, int flag)
                break;
        }
        default:
+               BUG();
                break;
        }
 }
 
-#ifdef CONFIG_SMP
-static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
+void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-       struct msi_desc *entry;
-       u32 address_hi, address_lo;
-       unsigned int irq = vector;
-       unsigned int dest_cpu = first_cpu(cpu_mask);
-
-       entry = (struct msi_desc *)msi_desc[vector];
-       if (!entry || !entry->dev)
-               return;
-
-       switch (entry->msi_attrib.type) {
+       struct msi_desc *entry = get_irq_data(irq);
+       switch(entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
-               int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI);
-
-               if (!pos)
-                       return;
-
-               pci_read_config_dword(entry->dev, msi_upper_address_reg(pos),
-                       &address_hi);
-               pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
-                       &address_lo);
-
-               msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
-
-               pci_write_config_dword(entry->dev, msi_upper_address_reg(pos),
-                       address_hi);
-               pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
-                       address_lo);
-               set_native_irq_info(irq, cpu_mask);
+               struct pci_dev *dev = entry->dev;
+               int pos = entry->msi_attrib.pos;
+               u16 data;
+
+               pci_read_config_dword(dev, msi_lower_address_reg(pos),
+                                       &msg->address_lo);
+               if (entry->msi_attrib.is_64) {
+                       pci_read_config_dword(dev, msi_upper_address_reg(pos),
+                                               &msg->address_hi);
+                       pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
+               } else {
+                       msg->address_hi = 0;
+                       pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
+               }
+               msg->data = data;
                break;
        }
        case PCI_CAP_ID_MSIX:
        {
-               int offset_hi =
-                       entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET;
-               int offset_lo =
-                       entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
-
-               address_hi = readl(entry->mask_base + offset_hi);
-               address_lo = readl(entry->mask_base + offset_lo);
+               void __iomem *base;
+               base = entry->mask_base +
+                       entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
 
-               msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
+               msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+               msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+               msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+               break;
+       }
+       default:
+               BUG();
+       }
+}
 
-               writel(address_hi, entry->mask_base + offset_hi);
-               writel(address_lo, entry->mask_base + offset_lo);
-               set_native_irq_info(irq, cpu_mask);
+void write_msi_msg(unsigned int irq, struct msi_msg *msg)
+{
+       struct msi_desc *entry = get_irq_data(irq);
+       switch (entry->msi_attrib.type) {
+       case PCI_CAP_ID_MSI:
+       {
+               struct pci_dev *dev = entry->dev;
+               int pos = entry->msi_attrib.pos;
+
+               pci_write_config_dword(dev, msi_lower_address_reg(pos),
+                                       msg->address_lo);
+               if (entry->msi_attrib.is_64) {
+                       pci_write_config_dword(dev, msi_upper_address_reg(pos),
+                                               msg->address_hi);
+                       pci_write_config_word(dev, msi_data_reg(pos, 1),
+                                               msg->data);
+               } else {
+                       pci_write_config_word(dev, msi_data_reg(pos, 0),
+                                               msg->data);
+               }
                break;
        }
-       default:
+       case PCI_CAP_ID_MSIX:
+       {
+               void __iomem *base;
+               base = entry->mask_base +
+                       entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+               writel(msg->address_lo,
+                       base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+               writel(msg->address_hi,
+                       base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+               writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
                break;
        }
-}
-#else
-#define set_msi_affinity NULL
-#endif /* CONFIG_SMP */
-
-static void mask_MSI_irq(unsigned int vector)
-{
-       msi_set_mask_bit(vector, 1);
-}
-
-static void unmask_MSI_irq(unsigned int vector)
-{
-       msi_set_mask_bit(vector, 0);
-}
-
-static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
-{
-       struct msi_desc *entry;
-       unsigned long flags;
-
-       spin_lock_irqsave(&msi_lock, flags);
-       entry = msi_desc[vector];
-       if (!entry || !entry->dev) {
-               spin_unlock_irqrestore(&msi_lock, flags);
-               return 0;
+       default:
+               BUG();
        }
-       entry->msi_attrib.state = 1;    /* Mark it active */
-       spin_unlock_irqrestore(&msi_lock, flags);
-
-       return 0;       /* never anything pending */
 }
 
-static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
+void mask_msi_irq(unsigned int irq)
 {
-       startup_msi_irq_wo_maskbit(vector);
-       unmask_MSI_irq(vector);
-       return 0;       /* never anything pending */
-}
-
-static void shutdown_msi_irq(unsigned int vector)
-{
-       struct msi_desc *entry;
-       unsigned long flags;
-
-       spin_lock_irqsave(&msi_lock, flags);
-       entry = msi_desc[vector];
-       if (entry && entry->dev)
-               entry->msi_attrib.state = 0;    /* Mark it not active */
-       spin_unlock_irqrestore(&msi_lock, flags);
+       msi_set_mask_bit(irq, 1);
 }
 
-static void end_msi_irq_wo_maskbit(unsigned int vector)
+void unmask_msi_irq(unsigned int irq)
 {
-       move_native_irq(vector);
-       ack_APIC_irq();
-}
-
-static void end_msi_irq_w_maskbit(unsigned int vector)
-{
-       move_native_irq(vector);
-       unmask_MSI_irq(vector);
-       ack_APIC_irq();
-}
-
-static void do_nothing(unsigned int vector)
-{
-}
-
-/*
- * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI-X Capability Structure.
- */
-static struct hw_interrupt_type msix_irq_type = {
-       .typename       = "PCI-MSI-X",
-       .startup        = startup_msi_irq_w_maskbit,
-       .shutdown       = shutdown_msi_irq,
-       .enable         = unmask_MSI_irq,
-       .disable        = mask_MSI_irq,
-       .ack            = mask_MSI_irq,
-       .end            = end_msi_irq_w_maskbit,
-       .set_affinity   = set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure with
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_w_maskbit_type = {
-       .typename       = "PCI-MSI",
-       .startup        = startup_msi_irq_w_maskbit,
-       .shutdown       = shutdown_msi_irq,
-       .enable         = unmask_MSI_irq,
-       .disable        = mask_MSI_irq,
-       .ack            = mask_MSI_irq,
-       .end            = end_msi_irq_w_maskbit,
-       .set_affinity   = set_msi_affinity
-};
-
-/*
- * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI Capability Structure without
- * Mask-and-Pending Bits.
- */
-static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
-       .typename       = "PCI-MSI",
-       .startup        = startup_msi_irq_wo_maskbit,
-       .shutdown       = shutdown_msi_irq,
-       .enable         = do_nothing,
-       .disable        = do_nothing,
-       .ack            = do_nothing,
-       .end            = end_msi_irq_wo_maskbit,
-       .set_affinity   = set_msi_affinity
-};
-
-static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
-static int assign_msi_vector(void)
-{
-       static int new_vector_avail = 1;
-       int vector;
-       unsigned long flags;
-
-       /*
-        * msi_lock is provided to ensure that successful allocation of MSI
-        * vector is assigned unique among drivers.
-        */
-       spin_lock_irqsave(&msi_lock, flags);
-
-       if (!new_vector_avail) {
-               int free_vector = 0;
-
-               /*
-                * vector_irq[] = -1 indicates that this specific vector is:
-                * - assigned for MSI (since MSI have no associated IRQ) or
-                * - assigned for legacy if less than 16, or
-                * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
-                * vector_irq[] = 0 indicates that this vector, previously
-                * assigned for MSI, is freed by hotplug removed operations.
-                * This vector will be reused for any subsequent hotplug added
-                * operations.
-                * vector_irq[] > 0 indicates that this vector is assigned for
-                * IOxAPIC IRQs. This vector and its value provides a 1-to-1
-                * vector-to-IOxAPIC IRQ mapping.
-                */
-               for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
-                       if (vector_irq[vector] != 0)
-                               continue;
-                       free_vector = vector;
-                       if (!msi_desc[vector])
-                               break;
-                       else
-                               continue;
-               }
-               if (!free_vector) {
-                       spin_unlock_irqrestore(&msi_lock, flags);
-                       return -EBUSY;
-               }
-               vector_irq[free_vector] = -1;
-               nr_released_vectors--;
-               spin_unlock_irqrestore(&msi_lock, flags);
-               if (msi_desc[free_vector] != NULL) {
-                       struct pci_dev *dev;
-                       int tail;
-
-                       /* free all linked vectors before re-assign */
-                       do {
-                               spin_lock_irqsave(&msi_lock, flags);
-                               dev = msi_desc[free_vector]->dev;
-                               tail = msi_desc[free_vector]->link.tail;
-                               spin_unlock_irqrestore(&msi_lock, flags);
-                               msi_free_vector(dev, tail, 1);
-                       } while (free_vector != tail);
-               }
-
-               return free_vector;
-       }
-       vector = assign_irq_vector(AUTO_ASSIGN);
-       last_alloc_vector = vector;
-       if (vector  == LAST_DEVICE_VECTOR)
-               new_vector_avail = 0;
-
-       spin_unlock_irqrestore(&msi_lock, flags);
-       return vector;
-}
-
-static int get_new_vector(void)
-{
-       int vector = assign_msi_vector();
-
-       if (vector > 0)
-               set_intr_gate(vector, interrupt[vector]);
-
-       return vector;
+       msi_set_mask_bit(irq, 0);
 }
 
+static int msi_free_irq(struct pci_dev* dev, int irq);
 static int msi_init(void)
 {
        static int status = -ENOMEM;
@@ -352,22 +176,6 @@ static int msi_init(void)
                return status;
        }
 
-       status = msi_arch_init();
-       if (status < 0) {
-               pci_msi_enable = 0;
-               printk(KERN_WARNING
-                      "PCI: MSI arch init failed.  MSI disabled.\n");
-               return status;
-       }
-
-       if (! msi_ops) {
-               printk(KERN_WARNING
-                      "PCI: MSI ops not registered. MSI disabled.\n");
-               status = -EINVAL;
-               return status;
-       }
-
-       last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
        status = msi_cache_init();
        if (status < 0) {
                pci_msi_enable = 0;
@@ -375,23 +183,9 @@ static int msi_init(void)
                return status;
        }
 
-       if (last_alloc_vector < 0) {
-               pci_msi_enable = 0;
-               printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
-               status = -EBUSY;
-               return status;
-       }
-       vector_irq[last_alloc_vector] = 0;
-       nr_released_vectors++;
-
        return status;
 }
 
-static int get_msi_vector(struct pci_dev *dev)
-{
-       return get_new_vector();
-}
-
 static struct msi_desc* alloc_msi_entry(void)
 {
        struct msi_desc *entry;
@@ -406,29 +200,44 @@ static struct msi_desc* alloc_msi_entry(void)
        return entry;
 }
 
-static void attach_msi_entry(struct msi_desc *entry, int vector)
+static void attach_msi_entry(struct msi_desc *entry, int irq)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&msi_lock, flags);
-       msi_desc[vector] = entry;
+       msi_desc[irq] = entry;
        spin_unlock_irqrestore(&msi_lock, flags);
 }
 
-static void irq_handler_init(int cap_id, int pos, int mask)
+static int create_msi_irq(void)
 {
-       unsigned long flags;
+       struct msi_desc *entry;
+       int irq;
 
-       spin_lock_irqsave(&irq_desc[pos].lock, flags);
-       if (cap_id == PCI_CAP_ID_MSIX)
-               irq_desc[pos].chip = &msix_irq_type;
-       else {
-               if (!mask)
-                       irq_desc[pos].chip = &msi_irq_wo_maskbit_type;
-               else
-                       irq_desc[pos].chip = &msi_irq_w_maskbit_type;
+       entry = alloc_msi_entry();
+       if (!entry)
+               return -ENOMEM;
+
+       irq = create_irq();
+       if (irq < 0) {
+               kmem_cache_free(msi_cachep, entry);
+               return -EBUSY;
        }
-       spin_unlock_irqrestore(&irq_desc[pos].lock, flags);
+
+       set_irq_data(irq, entry);
+
+       return irq;
+}
+
+static void destroy_msi_irq(unsigned int irq)
+{
+       struct msi_desc *entry;
+
+       entry = get_irq_data(irq);
+       set_irq_chip(irq, NULL);
+       set_irq_data(irq, NULL);
+       destroy_irq(irq);
+       kmem_cache_free(msi_cachep, entry);
 }
 
 static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
@@ -473,21 +282,21 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
        }
 }
 
-static int msi_lookup_vector(struct pci_dev *dev, int type)
+static int msi_lookup_irq(struct pci_dev *dev, int type)
 {
-       int vector;
+       int irq;
        unsigned long flags;
 
        spin_lock_irqsave(&msi_lock, flags);
-       for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
-               if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
-                       msi_desc[vector]->msi_attrib.type != type ||
-                       msi_desc[vector]->msi_attrib.default_vector != dev->irq)
+       for (irq = 0; irq < NR_IRQS; irq++) {
+               if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
+                       msi_desc[irq]->msi_attrib.type != type ||
+                       msi_desc[irq]->msi_attrib.default_irq != dev->irq)
                        continue;
                spin_unlock_irqrestore(&msi_lock, flags);
-               /* This pre-assigned MSI vector for this device
-                  already exits. Override dev->irq with this vector */
-               dev->irq = vector;
+               /* This pre-assigned MSI irq for this device
+                  already exits. Override dev->irq with this irq */
+               dev->irq = irq;
                return 0;
        }
        spin_unlock_irqrestore(&msi_lock, flags);
@@ -499,11 +308,6 @@ void pci_scan_msi_device(struct pci_dev *dev)
 {
        if (!dev)
                return;
-
-       if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0)
-               nr_msix_devices++;
-       else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0)
-               nr_reserved_vectors++;
 }
 
 #ifdef CONFIG_PM
@@ -577,7 +381,7 @@ int pci_save_msix_state(struct pci_dev *dev)
 {
        int pos;
        int temp;
-       int vector, head, tail = 0;
+       int irq, head, tail = 0;
        u16 control;
        struct pci_cap_saved_state *save_state;
 
@@ -599,33 +403,20 @@ int pci_save_msix_state(struct pci_dev *dev)
 
        /* save the table */
        temp = dev->irq;
-       if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+       if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
                kfree(save_state);
                return -EINVAL;
        }
 
-       vector = head = dev->irq;
+       irq = head = dev->irq;
        while (head != tail) {
-               int j;
-               void __iomem *base;
                struct msi_desc *entry;
 
-               entry = msi_desc[vector];
-               base = entry->mask_base;
-               j = entry->msi_attrib.entry_nr;
-
-               entry->address_lo_save =
-                       readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                             PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-               entry->address_hi_save =
-                       readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                             PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-               entry->data_save =
-                       readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                             PCI_MSIX_ENTRY_DATA_OFFSET);
-
-               tail = msi_desc[vector]->link.tail;
-               vector = tail;
+               entry = msi_desc[irq];
+               read_msi_msg(irq, &entry->msg_save);
+
+               tail = msi_desc[irq]->link.tail;
+               irq = tail;
        }
        dev->irq = temp;
 
@@ -638,9 +429,7 @@ void pci_restore_msix_state(struct pci_dev *dev)
 {
        u16 save;
        int pos;
-       int vector, head, tail = 0;
-       void __iomem *base;
-       int j;
+       int irq, head, tail = 0;
        struct msi_desc *entry;
        int temp;
        struct pci_cap_saved_state *save_state;
@@ -658,26 +447,15 @@ void pci_restore_msix_state(struct pci_dev *dev)
 
        /* route the table */
        temp = dev->irq;
-       if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX))
+       if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
                return;
-       vector = head = dev->irq;
+       irq = head = dev->irq;
        while (head != tail) {
-               entry = msi_desc[vector];
-               base = entry->mask_base;
-               j = entry->msi_attrib.entry_nr;
-
-               writel(entry->address_lo_save,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-               writel(entry->address_hi_save,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-               writel(entry->data_save,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_DATA_OFFSET);
-
-               tail = msi_desc[vector]->link.tail;
-               vector = tail;
+               entry = msi_desc[irq];
+               write_msi_msg(irq, &entry->msg_save);
+
+               tail = msi_desc[irq]->link.tail;
+               irq = tail;
        }
        dev->irq = temp;
 
@@ -686,104 +464,68 @@ void pci_restore_msix_state(struct pci_dev *dev)
 }
 #endif
 
-static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
-{
-       int status;
-       u32 address_hi;
-       u32 address_lo;
-       u32 data;
-       int pos, vector = dev->irq;
-       u16 control;
-
-       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-       pci_read_config_word(dev, msi_control_reg(pos), &control);
-
-       /* Configure MSI capability structure */
-       status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data);
-       if (status < 0)
-               return status;
-
-       pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo);
-       if (is_64bit_address(control)) {
-               pci_write_config_dword(dev,
-                       msi_upper_address_reg(pos), address_hi);
-               pci_write_config_word(dev,
-                       msi_data_reg(pos, 1), data);
-       } else
-               pci_write_config_word(dev,
-                       msi_data_reg(pos, 0), data);
-       if (entry->msi_attrib.maskbit) {
-               unsigned int maskbits, temp;
-               /* All MSIs are unmasked by default, Mask them all */
-               pci_read_config_dword(dev,
-                       msi_mask_bits_reg(pos, is_64bit_address(control)),
-                       &maskbits);
-               temp = (1 << multi_msi_capable(control));
-               temp = ((temp - 1) & ~temp);
-               maskbits |= temp;
-               pci_write_config_dword(dev,
-                       msi_mask_bits_reg(pos, is_64bit_address(control)),
-                       maskbits);
-       }
-
-       return 0;
-}
-
 /**
  * msi_capability_init - configure device's MSI capability structure
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
  * Setup the MSI capability structure of device function with a single
- * MSI vector, regardless of device function is capable of handling
+ * MSI irq, regardless of device function is capable of handling
  * multiple messages. A return of zero indicates the successful setup
- * of an entry zero with the new MSI vector or non-zero for otherwise.
+ * of an entry zero with the new MSI irq or non-zero for otherwise.
  **/
 static int msi_capability_init(struct pci_dev *dev)
 {
        int status;
        struct msi_desc *entry;
-       int pos, vector;
+       int pos, irq;
        u16 control;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        /* MSI Entry Initialization */
-       entry = alloc_msi_entry();
-       if (!entry)
-               return -ENOMEM;
+       irq = create_msi_irq();
+       if (irq < 0)
+               return irq;
 
-       vector = get_msi_vector(dev);
-       if (vector < 0) {
-               kmem_cache_free(msi_cachep, entry);
-               return -EBUSY;
-       }
-       entry->link.head = vector;
-       entry->link.tail = vector;
+       entry = get_irq_data(irq);
+       entry->link.head = irq;
+       entry->link.tail = irq;
        entry->msi_attrib.type = PCI_CAP_ID_MSI;
-       entry->msi_attrib.state = 0;                    /* Mark it not active */
+       entry->msi_attrib.is_64 = is_64bit_address(control);
        entry->msi_attrib.entry_nr = 0;
        entry->msi_attrib.maskbit = is_mask_bit_support(control);
-       entry->msi_attrib.default_vector = dev->irq;    /* Save IOAPIC IRQ */
-       dev->irq = vector;
-       entry->dev = dev;
+       entry->msi_attrib.default_irq = dev->irq;       /* Save IOAPIC IRQ */
+       entry->msi_attrib.pos = pos;
        if (is_mask_bit_support(control)) {
                entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
                                is_64bit_address(control));
        }
-       /* Replace with MSI handler */
-       irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
+       entry->dev = dev;
+       if (entry->msi_attrib.maskbit) {
+               unsigned int maskbits, temp;
+               /* All MSIs are unmasked by default, Mask them all */
+               pci_read_config_dword(dev,
+                       msi_mask_bits_reg(pos, is_64bit_address(control)),
+                       &maskbits);
+               temp = (1 << multi_msi_capable(control));
+               temp = ((temp - 1) & ~temp);
+               maskbits |= temp;
+               pci_write_config_dword(dev,
+                       msi_mask_bits_reg(pos, is_64bit_address(control)),
+                       maskbits);
+       }
        /* Configure MSI capability structure */
-       status = msi_register_init(dev, entry);
-       if (status != 0) {
-               dev->irq = entry->msi_attrib.default_vector;
-               kmem_cache_free(msi_cachep, entry);
+       status = arch_setup_msi_irq(irq, dev);
+       if (status < 0) {
+               destroy_msi_irq(irq);
                return status;
        }
 
-       attach_msi_entry(entry, vector);
+       attach_msi_entry(entry, irq);
        /* Set MSI enabled bits  */
        enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
+       dev->irq = irq;
        return 0;
 }
 
@@ -794,18 +536,15 @@ static int msi_capability_init(struct pci_dev *dev)
  * @nvec: number of @entries
  *
  * Setup the MSI-X capability structure of device function with a
- * single MSI-X vector. A return of zero indicates the successful setup of
- * requested MSI-X entries with allocated vectors or non-zero for otherwise.
+ * single MSI-X irq. A return of zero indicates the successful setup of
+ * requested MSI-X entries with allocated irqs or non-zero for otherwise.
  **/
 static int msix_capability_init(struct pci_dev *dev,
                                struct msix_entry *entries, int nvec)
 {
        struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
-       u32 address_hi;
-       u32 address_lo;
-       u32 data;
        int status;
-       int vector, pos, i, j, nr_entries, temp = 0;
+       int irq, pos, i, j, nr_entries, temp = 0;
        unsigned long phys_addr;
        u32 table_offset;
        u16 control;
@@ -827,65 +566,56 @@ static int msix_capability_init(struct pci_dev *dev,
 
        /* MSI-X Table Initialization */
        for (i = 0; i < nvec; i++) {
-               entry = alloc_msi_entry();
-               if (!entry)
+               irq = create_msi_irq();
+               if (irq < 0)
                        break;
-               vector = get_msi_vector(dev);
-               if (vector < 0) {
-                       kmem_cache_free(msi_cachep, entry);
-                       break;
-               }
 
+               entry = get_irq_data(irq);
                j = entries[i].entry;
-               entries[i].vector = vector;
+               entries[i].vector = irq;
                entry->msi_attrib.type = PCI_CAP_ID_MSIX;
-               entry->msi_attrib.state = 0;            /* Mark it not active */
+               entry->msi_attrib.is_64 = 1;
                entry->msi_attrib.entry_nr = j;
                entry->msi_attrib.maskbit = 1;
-               entry->msi_attrib.default_vector = dev->irq;
+               entry->msi_attrib.default_irq = dev->irq;
+               entry->msi_attrib.pos = pos;
                entry->dev = dev;
                entry->mask_base = base;
                if (!head) {
-                       entry->link.head = vector;
-                       entry->link.tail = vector;
+                       entry->link.head = irq;
+                       entry->link.tail = irq;
                        head = entry;
                } else {
                        entry->link.head = temp;
                        entry->link.tail = tail->link.tail;
-                       tail->link.tail = vector;
-                       head->link.head = vector;
+                       tail->link.tail = irq;
+                       head->link.head = irq;
                }
-               temp = vector;
+               temp = irq;
                tail = entry;
-               /* Replace with MSI-X handler */
-               irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
                /* Configure MSI-X capability structure */
-               status = msi_ops->setup(dev, vector,
-                                       &address_hi,
-                                       &address_lo,
-                                       &data);
-               if (status < 0)
+               status = arch_setup_msi_irq(irq, dev);
+               if (status < 0) {
+                       destroy_msi_irq(irq);
                        break;
+               }
 
-               writel(address_lo,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-               writel(address_hi,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-               writel(data,
-                       base + j * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_DATA_OFFSET);
-               attach_msi_entry(entry, vector);
+               attach_msi_entry(entry, irq);
        }
        if (i != nvec) {
+               int avail = i - 1;
                i--;
                for (; i >= 0; i--) {
-                       vector = (entries + i)->vector;
-                       msi_free_vector(dev, vector, 0);
+                       irq = (entries + i)->vector;
+                       msi_free_irq(dev, irq);
                        (entries + i)->vector = 0;
                }
-               return -EBUSY;
+               /* If we had some success report the number of irqs
+                * we succeeded in setting up.
+                */
+               if (avail <= 0)
+                       avail = -EBUSY;
+               return avail;
        }
        /* Set MSI-X enabled bits */
        enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
@@ -925,15 +655,14 @@ int pci_msi_supported(struct pci_dev * dev)
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
  * Setup the MSI capability structure of device function with
- * a single MSI vector upon its software driver call to request for
+ * a single MSI irq upon its software driver call to request for
  * MSI mode enabled on its hardware device function. A return of zero
  * indicates the successful setup of an entry zero with the new MSI
- * vector or non-zero for otherwise.
+ * irq or non-zero for otherwise.
  **/
 int pci_enable_msi(struct pci_dev* dev)
 {
        int pos, temp, status;
-       u16 control;
 
        if (pci_msi_supported(dev) < 0)
                return -EINVAL;
@@ -948,52 +677,25 @@ int pci_enable_msi(struct pci_dev* dev)
        if (!pos)
                return -EINVAL;
 
-       if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-               /* Lookup Sucess */
-               unsigned long flags;
+       WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
 
-               pci_read_config_word(dev, msi_control_reg(pos), &control);
-               if (control & PCI_MSI_FLAGS_ENABLE)
-                       return 0;       /* Already in MSI mode */
-               spin_lock_irqsave(&msi_lock, flags);
-               if (!vector_irq[dev->irq]) {
-                       msi_desc[dev->irq]->msi_attrib.state = 0;
-                       vector_irq[dev->irq] = -1;
-                       nr_released_vectors--;
-                       spin_unlock_irqrestore(&msi_lock, flags);
-                       status = msi_register_init(dev, msi_desc[dev->irq]);
-                       if (status == 0)
-                               enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
-                       return status;
-               }
-               spin_unlock_irqrestore(&msi_lock, flags);
-               dev->irq = temp;
-       }
-       /* Check whether driver already requested for MSI-X vectors */
+       /* Check whether driver already requested for MSI-X irqs */
        pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+       if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
                        printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
-                              "Device already has MSI-X vectors assigned\n",
+                              "Device already has MSI-X irq assigned\n",
                               pci_name(dev));
                        dev->irq = temp;
                        return -EINVAL;
        }
        status = msi_capability_init(dev);
-       if (!status) {
-               if (!pos)
-                       nr_reserved_vectors--;  /* Only MSI capable */
-               else if (nr_msix_devices > 0)
-                       nr_msix_devices--;      /* Both MSI and MSI-X capable,
-                                                  but choose enabling MSI */
-       }
-
        return status;
 }
 
 void pci_disable_msi(struct pci_dev* dev)
 {
        struct msi_desc *entry;
-       int pos, default_vector;
+       int pos, default_irq;
        u16 control;
        unsigned long flags;
 
@@ -1010,41 +712,41 @@ void pci_disable_msi(struct pci_dev* dev)
        if (!(control & PCI_MSI_FLAGS_ENABLE))
                return;
 
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
+
        spin_lock_irqsave(&msi_lock, flags);
        entry = msi_desc[dev->irq];
        if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
                spin_unlock_irqrestore(&msi_lock, flags);
                return;
        }
-       if (entry->msi_attrib.state) {
+       if (irq_has_action(dev->irq)) {
                spin_unlock_irqrestore(&msi_lock, flags);
                printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
-                      "free_irq() on MSI vector %d\n",
+                      "free_irq() on MSI irq %d\n",
                       pci_name(dev), dev->irq);
-               BUG_ON(entry->msi_attrib.state > 0);
+               BUG_ON(irq_has_action(dev->irq));
        } else {
-               vector_irq[dev->irq] = 0; /* free it */
-               nr_released_vectors++;
-               default_vector = entry->msi_attrib.default_vector;
+               default_irq = entry->msi_attrib.default_irq;
                spin_unlock_irqrestore(&msi_lock, flags);
-               /* Restore dev->irq to its default pin-assertion vector */
-               dev->irq = default_vector;
-               disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
-                                       PCI_CAP_ID_MSI);
+               msi_free_irq(dev, dev->irq);
+
+               /* Restore dev->irq to its default pin-assertion irq */
+               dev->irq = default_irq;
        }
 }
 
-static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
+static int msi_free_irq(struct pci_dev* dev, int irq)
 {
        struct msi_desc *entry;
        int head, entry_nr, type;
        void __iomem *base;
        unsigned long flags;
 
-       msi_ops->teardown(vector);
+       arch_teardown_msi_irq(irq);
 
        spin_lock_irqsave(&msi_lock, flags);
-       entry = msi_desc[vector];
+       entry = msi_desc[irq];
        if (!entry || entry->dev != dev) {
                spin_unlock_irqrestore(&msi_lock, flags);
                return -EINVAL;
@@ -1056,100 +758,42 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
        msi_desc[entry->link.head]->link.tail = entry->link.tail;
        msi_desc[entry->link.tail]->link.head = entry->link.head;
        entry->dev = NULL;
-       if (!reassign) {
-               vector_irq[vector] = 0;
-               nr_released_vectors++;
-       }
-       msi_desc[vector] = NULL;
+       msi_desc[irq] = NULL;
        spin_unlock_irqrestore(&msi_lock, flags);
 
-       kmem_cache_free(msi_cachep, entry);
+       destroy_msi_irq(irq);
 
        if (type == PCI_CAP_ID_MSIX) {
-               if (!reassign)
-                       writel(1, base +
-                               entry_nr * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+               writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
+                       PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
 
-               if (head == vector)
+               if (head == irq)
                        iounmap(base);
        }
 
        return 0;
 }
 
-static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
-{
-       int vector = head, tail = 0;
-       int i, j = 0, nr_entries = 0;
-       void __iomem *base;
-       unsigned long flags;
-
-       spin_lock_irqsave(&msi_lock, flags);
-       while (head != tail) {
-               nr_entries++;
-               tail = msi_desc[vector]->link.tail;
-               if (entries[0].entry == msi_desc[vector]->msi_attrib.entry_nr)
-                       j = vector;
-               vector = tail;
-       }
-       if (*nvec > nr_entries) {
-               spin_unlock_irqrestore(&msi_lock, flags);
-               *nvec = nr_entries;
-               return -EINVAL;
-       }
-       vector = ((j > 0) ? j : head);
-       for (i = 0; i < *nvec; i++) {
-               j = msi_desc[vector]->msi_attrib.entry_nr;
-               msi_desc[vector]->msi_attrib.state = 0; /* Mark it not active */
-               vector_irq[vector] = -1;                /* Mark it busy */
-               nr_released_vectors--;
-               entries[i].vector = vector;
-               if (j != (entries + i)->entry) {
-                       base = msi_desc[vector]->mask_base;
-                       msi_desc[vector]->msi_attrib.entry_nr =
-                               (entries + i)->entry;
-                       writel( readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET), base +
-                               (entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-                       writel( readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET), base +
-                               (entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-                       writel( (readl(base + j * PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_DATA_OFFSET) & 0xff00) | vector,
-                               base + (entries+i)->entry*PCI_MSIX_ENTRY_SIZE +
-                               PCI_MSIX_ENTRY_DATA_OFFSET);
-               }
-               vector = msi_desc[vector]->link.tail;
-       }
-       spin_unlock_irqrestore(&msi_lock, flags);
-
-       return 0;
-}
-
 /**
  * pci_enable_msix - configure device's MSI-X capability structure
  * @dev: pointer to the pci_dev data structure of MSI-X device function
  * @entries: pointer to an array of MSI-X entries
- * @nvec: number of MSI-X vectors requested for allocation by device driver
+ * @nvec: number of MSI-X irqs requested for allocation by device driver
  *
  * Setup the MSI-X capability structure of device function with the number
- * of requested vectors upon its software driver call to request for
+ * of requested irqs upon its software driver call to request for
  * MSI-X mode enabled on its hardware device function. A return of zero
  * indicates the successful configuration of MSI-X capability structure
- * with new allocated MSI-X vectors. A return of < 0 indicates a failure.
+ * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
  * Or a return of > 0 indicates that driver request is exceeding the number
- * of vectors available. Driver should use the returned value to re-send
+ * of irqs available. Driver should use the returned value to re-send
  * its request.
  **/
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
-       int status, pos, nr_entries, free_vectors;
+       int status, pos, nr_entries;
        int i, j, temp;
        u16 control;
-       unsigned long flags;
 
        if (!entries || pci_msi_supported(dev) < 0)
                return -EINVAL;
@@ -1163,9 +807,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
                return -EINVAL;
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
-       if (control & PCI_MSIX_FLAGS_ENABLE)
-               return -EINVAL;                 /* Already in MSI-X mode */
-
        nr_entries = multi_msix_capable(control);
        if (nvec > nr_entries)
                return -EINVAL;
@@ -1180,56 +821,18 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
                }
        }
        temp = dev->irq;
-       if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-               /* Lookup Sucess */
-               nr_entries = nvec;
-               /* Reroute MSI-X table */
-               if (reroute_msix_table(dev->irq, entries, &nr_entries)) {
-                       /* #requested > #previous-assigned */
-                       dev->irq = temp;
-                       return nr_entries;
-               }
-               dev->irq = temp;
-               enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
-               return 0;
-       }
-       /* Check whether driver already requested for MSI vector */
+       WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
+
+       /* Check whether driver already requested for MSI irq */
        if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
-               !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
+               !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
                printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
-                      "Device already has an MSI vector assigned\n",
+                      "Device already has an MSI irq assigned\n",
                       pci_name(dev));
                dev->irq = temp;
                return -EINVAL;
        }
-
-       spin_lock_irqsave(&msi_lock, flags);
-       /*
-        * msi_lock is provided to ensure that enough vectors resources are
-        * available before granting.
-        */
-       free_vectors = pci_vector_resources(last_alloc_vector,
-                               nr_released_vectors);
-       /* Ensure that each MSI/MSI-X device has one vector reserved by
-          default to avoid any MSI-X driver to take all available
-          resources */
-       free_vectors -= nr_reserved_vectors;
-       /* Find the average of free vectors among MSI-X devices */
-       if (nr_msix_devices > 0)
-               free_vectors /= nr_msix_devices;
-       spin_unlock_irqrestore(&msi_lock, flags);
-
-       if (nvec > free_vectors) {
-               if (free_vectors > 0)
-                       return free_vectors;
-               else
-                       return -EBUSY;
-       }
-
        status = msix_capability_init(dev, entries, nvec);
-       if (!status && nr_msix_devices > 0)
-               nr_msix_devices--;
-
        return status;
 }
 
@@ -1251,53 +854,47 @@ void pci_disable_msix(struct pci_dev* dev)
        if (!(control & PCI_MSIX_FLAGS_ENABLE))
                return;
 
+       disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
+
        temp = dev->irq;
-       if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-               int state, vector, head, tail = 0, warning = 0;
+       if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+               int irq, head, tail = 0, warning = 0;
                unsigned long flags;
 
-               vector = head = dev->irq;
-               spin_lock_irqsave(&msi_lock, flags);
+               irq = head = dev->irq;
+               dev->irq = temp;                        /* Restore pin IRQ */
                while (head != tail) {
-                       state = msi_desc[vector]->msi_attrib.state;
-                       if (state)
+                       spin_lock_irqsave(&msi_lock, flags);
+                       tail = msi_desc[irq]->link.tail;
+                       spin_unlock_irqrestore(&msi_lock, flags);
+                       if (irq_has_action(irq))
                                warning = 1;
-                       else {
-                               vector_irq[vector] = 0; /* free it */
-                               nr_released_vectors++;
-                       }
-                       tail = msi_desc[vector]->link.tail;
-                       vector = tail;
+                       else if (irq != head)   /* Release MSI-X irq */
+                               msi_free_irq(dev, irq);
+                       irq = tail;
                }
-               spin_unlock_irqrestore(&msi_lock, flags);
+               msi_free_irq(dev, irq);
                if (warning) {
-                       dev->irq = temp;
                        printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
-                              "free_irq() on all MSI-X vectors\n",
+                              "free_irq() on all MSI-X irqs\n",
                               pci_name(dev));
                        BUG_ON(warning > 0);
-               } else {
-                       dev->irq = temp;
-                       disable_msi_mode(dev,
-                               pci_find_capability(dev, PCI_CAP_ID_MSIX),
-                               PCI_CAP_ID_MSIX);
-
                }
        }
 }
 
 /**
- * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
+ * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state
  * @dev: pointer to the pci_dev data structure of MSI(X) device function
  *
  * Being called during hotplug remove, from which the device function
- * is hot-removed. All previous assigned MSI/MSI-X vectors, if
+ * is hot-removed. All previous assigned MSI/MSI-X irqs, if
  * allocated for this device function, are reclaimed to unused state,
  * which may be used later on.
  **/
 void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 {
-       int state, pos, temp;
+       int pos, temp;
        unsigned long flags;
 
        if (!pci_msi_enable || !dev)
@@ -1305,42 +902,38 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 
        temp = dev->irq;                /* Save IOAPIC IRQ */
        pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-               spin_lock_irqsave(&msi_lock, flags);
-               state = msi_desc[dev->irq]->msi_attrib.state;
-               spin_unlock_irqrestore(&msi_lock, flags);
-               if (state) {
+       if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
+               if (irq_has_action(dev->irq)) {
                        printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-                              "called without free_irq() on MSI vector %d\n",
+                              "called without free_irq() on MSI irq %d\n",
                               pci_name(dev), dev->irq);
-                       BUG_ON(state > 0);
-               } else /* Release MSI vector assigned to this device */
-                       msi_free_vector(dev, dev->irq, 0);
+                       BUG_ON(irq_has_action(dev->irq));
+               } else /* Release MSI irq assigned to this device */
+                       msi_free_irq(dev, dev->irq);
                dev->irq = temp;                /* Restore IOAPIC IRQ */
        }
        pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-               int vector, head, tail = 0, warning = 0;
+       if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+               int irq, head, tail = 0, warning = 0;
                void __iomem *base = NULL;
 
-               vector = head = dev->irq;
+               irq = head = dev->irq;
                while (head != tail) {
                        spin_lock_irqsave(&msi_lock, flags);
-                       state = msi_desc[vector]->msi_attrib.state;
-                       tail = msi_desc[vector]->link.tail;
-                       base = msi_desc[vector]->mask_base;
+                       tail = msi_desc[irq]->link.tail;
+                       base = msi_desc[irq]->mask_base;
                        spin_unlock_irqrestore(&msi_lock, flags);
-                       if (state)
+                       if (irq_has_action(irq))
                                warning = 1;
-                       else if (vector != head) /* Release MSI-X vector */
-                               msi_free_vector(dev, vector, 0);
-                       vector = tail;
+                       else if (irq != head) /* Release MSI-X irq */
+                               msi_free_irq(dev, irq);
+                       irq = tail;
                }
-               msi_free_vector(dev, vector, 0);
+               msi_free_irq(dev, irq);
                if (warning) {
                        iounmap(base);
                        printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
-                              "called without free_irq() on all MSI-X vectors\n",
+                              "called without free_irq() on all MSI-X irqs\n",
                               pci_name(dev));
                        BUG_ON(warning > 0);
                }
index 56951c39d3a3e8c8d6656f2b2a2f1ac49321f475..f0cca1772f9c5e6e4d315682788afea763db5605 100644 (file)
@@ -6,84 +6,6 @@
 #ifndef MSI_H
 #define MSI_H
 
-/*
- * MSI operation vector.  Used by the msi core code (drivers/pci/msi.c)
- * to abstract platform-specific tasks relating to MSI address generation
- * and resource management.
- */
-struct msi_ops {
-       /**
-        * setup - generate an MSI bus address and data for a given vector
-        * @pdev: PCI device context (in)
-        * @vector: vector allocated by the msi core (in)
-        * @addr_hi: upper 32 bits of PCI bus MSI address (out)
-        * @addr_lo: lower 32 bits of PCI bus MSI address (out)
-        * @data: MSI data payload (out)
-        *
-        * Description: The setup op is used to generate a PCI bus addres and
-        * data which the msi core will program into the card MSI capability
-        * registers.  The setup routine is responsible for picking an initial
-        * cpu to target the MSI at.  The setup routine is responsible for
-        * examining pdev to determine the MSI capabilities of the card and
-        * generating a suitable address/data.  The setup routine is
-        * responsible for allocating and tracking any system resources it
-        * needs to route the MSI to the cpu it picks, and for associating
-        * those resources with the passed in vector.
-        *
-        * Returns 0 if the MSI address/data was successfully setup.
-        **/
-
-       int     (*setup)    (struct pci_dev *pdev, unsigned int vector,
-                            u32 *addr_hi, u32 *addr_lo, u32 *data);
-
-       /**
-        * teardown - release resources allocated by setup
-        * @vector: vector context for resources (in)
-        *
-        * Description:  The teardown op is used to release any resources
-        * that were allocated in the setup routine associated with the passed
-        * in vector.
-        **/
-
-       void    (*teardown) (unsigned int vector);
-
-       /**
-        * target - retarget an MSI at a different cpu
-        * @vector: vector context for resources (in)
-        * @cpu:  new cpu to direct vector at (in)
-        * @addr_hi: new value of PCI bus upper 32 bits (in/out)
-        * @addr_lo: new value of PCI bus lower 32 bits (in/out)
-        *
-        * Description:  The target op is used to redirect an MSI vector
-        * at a different cpu.  addr_hi/addr_lo coming in are the existing
-        * values that the MSI core has programmed into the card.  The
-        * target code is responsible for freeing any resources (if any)
-        * associated with the old address, and generating a new PCI bus
-        * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
-        **/
-
-       void    (*target)   (unsigned int vector, unsigned int cpu,
-                            u32 *addr_hi, u32 *addr_lo);
-};
-
-extern int msi_register(struct msi_ops *ops);
-
-#include <asm/msi.h>
-
-/*
- * Assume the maximum number of hot plug slots supported by the system is about
- * ten. The worstcase is that each of these slots is hot-added with a device,
- * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
- * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
- * as below to ensure at least one message is assigned to each detected MSI/
- * MSI-X device function.
- */
-#define NR_HP_RESERVED_VECTORS         20
-
-extern int vector_irq[NR_VECTORS];
-extern void (*interrupt[NR_IRQS])(void);
-extern int pci_vector_resources(int last, int nr_released);
-
 /*
  * MSI-X Address Register
  */
@@ -110,8 +32,8 @@ extern int pci_vector_resources(int last, int nr_released);
        (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
 #define multi_msi_enable(control, num) \
        control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
-#define is_64bit_address(control)      (control & PCI_MSI_FLAGS_64BIT)
-#define is_mask_bit_support(control)   (control & PCI_MSI_FLAGS_MASKBIT)
+#define is_64bit_address(control)      (!!(control & PCI_MSI_FLAGS_64BIT))
+#define is_mask_bit_support(control)   (!!(control & PCI_MSI_FLAGS_MASKBIT))
 #define msi_enable(control, num) multi_msi_enable(control, num); \
        control |= PCI_MSI_FLAGS_ENABLE
 
@@ -125,32 +47,4 @@ extern int pci_vector_resources(int last, int nr_released);
 #define msix_mask(address)             (address | PCI_MSIX_FLAGS_BITMASK)
 #define msix_is_pending(address)       (address & PCI_MSIX_FLAGS_PENDMASK)
 
-struct msi_desc {
-       struct {
-               __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
-               __u8    maskbit : 1;    /* mask-pending bit supported ?   */
-               __u8    state   : 1;    /* {0: free, 1: busy}             */
-               __u8    reserved: 1;    /* reserved                       */
-               __u8    entry_nr;       /* specific enabled entry         */
-               __u8    default_vector; /* default pre-assigned vector    */
-               __u8    unused;         /* formerly unused destination cpu*/
-       }msi_attrib;
-
-       struct {
-               __u16   head;
-               __u16   tail;
-       }link;
-
-       void __iomem *mask_base;
-       struct pci_dev *dev;
-
-#ifdef CONFIG_PM
-       /* PM save area for MSIX address/data */
-
-       u32     address_hi_save;
-       u32     address_lo_save;
-       u32     data_save;
-#endif
-};
-
 #endif /* MSI_H */
index 54404917be9a5ebbaaa77d694d118eba1298a7d3..8f7bcf56f1498d17064916d9986433e4e557631b 100644 (file)
@@ -55,16 +55,16 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
        list_for_each_entry(dev, &bus->devices, bus_list) {
                u16 class = dev->class >> 8;
 
-               /* Don't touch classless devices or host bridges. */
+               /* Don't touch classless devices or host bridges or ioapics.  */
                if (class == PCI_CLASS_NOT_DEFINED ||
                    class == PCI_CLASS_BRIDGE_HOST)
                        continue;
 
-               /* Don't touch ioapics if it has the assigned resources. */
+               /* Don't touch ioapic devices already enabled by firmware */
                if (class == PCI_CLASS_SYSTEM_PIC) {
-                       res = &dev->resource[0];
-                       if (res[0].start || res[1].start || res[2].start ||
-                           res[3].start || res[4].start || res[5].start)
+                       u16 command;
+                       pci_read_config_word(dev, PCI_COMMAND, &command);
+                       if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
                                continue;
                }
 
index 0b2d2c3579a77b655f723b0d59d4a9b2d16de211..4142115d298ef9a4e0cbd16190fa7ae039201a91 100644 (file)
@@ -15,4 +15,4 @@ config RAPIDIO_DISC_TIMEOUT
        default "30"
        ---help---
          Amount of time a discovery node waits for a host to complete
-         enumeration beforing giving up.
+         enumeration before giving up.
index cc5032b6f42ac45c9aba4f0ff896b17585a6c813..3f0f7b8fa813057d777b908b260166624dfa3c2a 100644 (file)
@@ -141,9 +141,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
 
        dev_dbg(dev, "%s secs=%d, mins=%d, "
                "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
-               "write", dt->tm_sec, dt->tm_min,
-               dt->tm_hour, dt->tm_mday,
-               dt->tm_mon, dt->tm_year, dt->tm_wday);
+               "write", t->tm_sec, t->tm_min,
+               t->tm_hour, t->tm_mday,
+               t->tm_mon, t->tm_year, t->tm_wday);
 
        *buf++ = 0;             /* first register addr */
        buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
index 9c68ec99afa5776ad23d039efd693b02ef2d4890..67e816a9a39fdc5c0f64e929f95cc6dbc4fcf58b 100644 (file)
@@ -55,7 +55,7 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
        }
 
        dev_dbg(&client->dev,
-               "%s: raw read data - counters=%02x,%02x,%02x,%02x\n"
+               "%s: raw read data - counters=%02x,%02x,%02x,%02x\n",
                __FUNCTION__, buf[0], buf[1], buf[2], buf[3]);
 
        time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
@@ -96,7 +96,7 @@ static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm)
        unsigned long secs;
 
        dev_dbg(&client->dev,
-               "%s: secs=%d, mins=%d, hours=%d, ",
+               "%s: secs=%d, mins=%d, hours=%d, "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
                __FUNCTION__,
                tm->tm_sec, tm->tm_min, tm->tm_hour,
index 9eeef964663ac84597f7d1ab1d754e1df302063c..2f0b7772419276cd8f1f8b0bb7157973ecce0574 100644 (file)
@@ -1,4 +1,4 @@
-/* drivers/char/max6902.c
+/* drivers/rtc/rtc-max6902.c
  *
  * Copyright (C) 2006 8D Technologies inc.
  * Copyright (C) 2004 Compulab Ltd.
index bbdad099471d43b65d33ec05161f1f88e01b0dac..2a86632580f16e2cc0d010fb938af67c6df81be8 100644 (file)
@@ -91,7 +91,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
        unsigned char buf[8] = { RS5C372_REG_BASE };
 
        dev_dbg(&client->dev,
-               "%s: secs=%d, mins=%d, hours=%d ",
+               "%s: secs=%d, mins=%d, hours=%d "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
                __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour,
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
@@ -126,7 +126,7 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim)
                return -EIO;
        }
 
-       dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, trim);
+       dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim);
 
        if (osc)
                *osc = (buf & RS5C372_TRIM_XSL) ? 32000 : 32768;
index 836a58bb0305436a0ca30c35c74c80489620ee31..40b6fc86f6a8301a5c0fec1e2c3a6dba5a807d4f 100644 (file)
@@ -10,8 +10,6 @@
  *                     timer interrupts.  We use a timer to periodically 
  *                     reset 'stopped' watchdogs on affected platforms.
  *
- * TODO:       DevFS support (/dev/watchdogs/0 ... /dev/watchdogs/2)
- *
  * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
  */
 
index dab082002e6fe572f10e9e46f4cafecba2f3dbc7..c6dfb6fa13bf4192583a52556867374d570374ec 100644 (file)
@@ -40,10 +40,10 @@ config SCSI_PROC_FS
        default y
        ---help---
          This option enables support for the various files in
-         /proc/scsi.  In Linux 2.6 this has been superceeded by
+         /proc/scsi.  In Linux 2.6 this has been superseded by
          files in sysfs but many legacy applications rely on this.
 
-         If unusure say Y.
+         If unsure say Y.
 
 comment "SCSI support type (disk, tape, CD-ROM)"
        depends on SCSI
@@ -85,7 +85,7 @@ config CHR_DEV_OSST
        tristate "SCSI OnStream SC-x0 tape support"
        depends on SCSI
        ---help---
-         The OnStream SC-x0 SCSI tape drives can not be driven by the
+         The OnStream SC-x0 SCSI tape drives cannot be driven by the
          standard st driver, but instead need this special osst driver and
          use the  /dev/osstX char device nodes (major 206).  Via usb-storage
          and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
index 7955ebe8e1e8d6d8be83c5f659efb878c8cedb85..911ea1756e554e30beaccaed9662a1cd3a123cb2 100644 (file)
@@ -22,12 +22,12 @@ config AIC79XX_CMDS_PER_DEVICE
        to be used for any device.  The aic7xxx driver will automatically
        vary this number based on device behavior.  For devices with a
        fixed maximum, the driver will eventually lock to this maximum
-       and display a console message inidicating this value.
+       and display a console message indicating this value.
 
        Due to resource allocation issues in the Linux SCSI mid-layer, using
        a high number of commands per device may result in memory allocation
        failures when many devices are attached to the system.  For this reason,
-       the default is set to 32.  Higher values may result in higer performance
+       the default is set to 32.  Higher values may result in higher performance
        on some devices.  The upper bound is 253.  0 disables tagged queueing.
 
        Per device tag depth can be controlled via the kernel command line
index 5517da5855f0037d174d8696dbb0053a7b91cce9..cd93f9a8611f99fd2a015e6d3bbd6e84d7557458 100644 (file)
@@ -27,12 +27,12 @@ config AIC7XXX_CMDS_PER_DEVICE
        to be used for any device.  The aic7xxx driver will automatically
        vary this number based on device behavior.  For devices with a
        fixed maximum, the driver will eventually lock to this maximum
-       and display a console message inidicating this value.
+       and display a console message indicating this value.
 
        Due to resource allocation issues in the Linux SCSI mid-layer, using
        a high number of commands per device may result in memory allocation
        failures when many devices are attached to the system.  For this reason,
-       the default is set to 32.  Higher values may result in higer performance
+       the default is set to 32.  Higher values may result in higher performance
        on some devices.  The upper bound is 253.  0 disables tagged queueing.
 
        Per device tag depth can be controlled via the kernel command line
index a28940156703097e0349a0f5cc5900eaa62296e9..4385e9e3ded68abbe895189866e415c989f5c5f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/drivers/scsi/arxescsi.c
+ * linux/drivers/scsi/arm/arxescsi.c
  *
  * Copyright (C) 1997-2000 Russell King, Stefan Hanske
  *
index 57438326b07f94549e32705801e16e8ced09acd5..76d83ade9857ea4efc696a123538d5df7d581961 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/char/21285.c
+ * linux/drivers/serial/21285.c
  *
  * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
  *
index d926272a40db59ed23a956078e90b58a640f0e84..653098bc2dd51ca5c2dedb89751cd90a0bab22b8 100644 (file)
@@ -121,7 +121,7 @@ config SERIAL_8250_RUNTIME_UARTS
        default "4"
        help
          Set this to the maximum number of serial ports you want
-         the kernel to register at boot time.  This can be overriden
+         the kernel to register at boot time.  This can be overridden
          with the module parameter "nr_uarts", or boot-time parameter
          8250.nr_uarts
 
@@ -205,7 +205,7 @@ config SERIAL_8250_BOCA
        depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
        help
          Say Y here if you have a Boca serial board.  Please read the Boca
-         mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto>
+         mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
 
          To compile this driver as a module, choose M here: the module
          will be called 8250_boca.
@@ -667,7 +667,7 @@ config SERIAL_68328
        depends on M68328 || M68EZ328 || M68VZ328
        help
          This driver supports the built-in serial port of the Motorola 68328
-         (standard, EZ and VZ varities).
+         (standard, EZ and VZ varieties).
 
 config SERIAL_68328_RTS_CTS
        bool "Support RTS/CTS on 68328 serial port"
index 5d867ab581b71f483c82e0832328ff98b6088882..5eb49ea63bfe4b76b2ce8449422d065c7acce890 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/serial/cpm_uart_cpm1.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
  *
  * Driver for CPM (SCC/SMC) serial ports
  * 
index a663300d3476b4222d441e8d648ef63b6f86b017..4b779111eaf9cc43e776ff3aff1a229d04fb0606 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/serial/cpm_uart_cpm2.h
+ * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
  *
  * Driver for CPM (SCC/SMC) serial ports
  * 
index 550ddfa71a4378d5f653a1cc885f01c0cf507aac..b450cbaa3a0baf91d445c5a43b0dd8d66b701646 100644 (file)
@@ -64,7 +64,7 @@ config USB_XUSBATM
          Say Y here if you have a DSL USB modem not explicitly supported by
          another USB DSL drivers.  In order to use your modem you will need to
          pass the vendor ID, product ID, and endpoint numbers for transmission
-         and reception as module parameters.  You may need to initialize the
+         and reception as module parameters.  You may need to initialize
          the modem using a user space utility (a firmware loader for example).
 
          To compile this driver as a module, choose M here: the
index c376c655c5defc8f6a0693430c29663f6b4e2a44..f794f07cfb3330f92ebfb135f1f0b8e601613594 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/usb/file.c
+ * drivers/usb/core/file.c
  *
  * (C) Copyright Linus Torvalds 1999
  * (C) Copyright Johannes Erdfelt 1999-2001
index e4df9edf1bc02bcfaa65f96f74730cb37f1e65bd..467cb02832f312f4af19417bdc3c6e213e0a7084 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * drivers/usb/usb.c
+ * drivers/usb/core/usb.c
  *
  * (C) Copyright Linus Torvalds 1999
  * (C) Copyright Johannes Erdfelt 1999-2001
index 8e5dd6f29d0bc18ed7c5b7ac453f67475cd1125d..bbbc82a8336a4f65858f815f586541b99091fb4c 100644 (file)
@@ -7,7 +7,7 @@
 #
 #  - Host systems (like PCs) need CONFIG_USB (with "A" jacks).
 #  - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks).
-#  - Some systems have both kinds of of controller.
+#  - Some systems have both kinds of controllers.
 #
 # With help from a special transceiver and a "Mini-AB" jack, systems with
 # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG).
index 422a4b288e346f589687aada8950d294dfbf469a..fe2c4cd53f5a101e43665a6a6564809f3bb90f8d 100644 (file)
@@ -119,7 +119,7 @@ config USB_STORAGE_ALAUDA
          Say Y here to include additional code to support the Olympus MAUSB-10
          and Fujifilm DPC-R1 USB Card reader/writer devices.
 
-         These devices are based on the Alauda chip and support support both
+         These devices are based on the Alauda chip and support both
          XD and SmartMedia cards.
 
 config USB_STORAGE_ONETOUCH
index a1c8923b0bf5ae95b52fe3e28b8c261e6db5609c..daaa486159cf37ae64d5329150466bf839272bdc 100644 (file)
@@ -188,7 +188,7 @@ config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
        bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC"
        help
          This is an implementation of the Sharp LQ035Q7DB02, a 3.5"
-         color QVGA, HRTFT panel.  The LogicPD device includes an
+         color QVGA, HRTFT panel.  The LogicPD device includes
          an integrated HRTFT controller IC.
          The native resolution is 240x320.
 
@@ -403,7 +403,7 @@ config FB_ARC
          is based on the KS-108 lcd controller and is typically a matrix
          of 2*n chips. This driver was tested with a 128x64 panel. This
          driver supports it for use with x86 SBCs through a 16 bit GPIO
-         interface (8 bit data, 8 bit control). If you anticpate using
+         interface (8 bit data, 8 bit control). If you anticipate using
          this driver, say Y or M; otherwise say N. You must specify the
          GPIO IO address to be used for setting control and data.
 
@@ -771,7 +771,7 @@ config FB_RIVA_DEBUG
        default n
        help
          Say Y here if you want the Riva driver to output all sorts
-         of debugging informations to provide to the maintainer when
+         of debugging information to provide to the maintainer when
          something goes wrong.
 
 config FB_RIVA_BACKLIGHT
@@ -865,7 +865,7 @@ config FB_INTEL_DEBUG
        depends on FB_INTEL
        ---help---
          Say Y here if you want the Intel driver to output all sorts
-         of debugging informations to provide to the maintainer when
+         of debugging information to provide to the maintainer when
          something goes wrong.
 
 config FB_INTEL_I2C
@@ -1062,7 +1062,7 @@ config FB_RADEON_DEBUG
        default n
        help
          Say Y here if you want the Radeon driver to output all sorts
-         of debugging informations to provide to the maintainer when
+         of debugging information to provide to the maintainer when
          something goes wrong.
 
 config FB_ATY128
index b120896c8ab455eb0e99d9454199a9847567e20f..a433cc78ef90b1d7c11639c52c838ae56457f504 100644 (file)
@@ -1843,7 +1843,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
                for (i = 0; propnames[i] != NULL; ++i) {
                        pedid = get_property(dp, propnames[i], NULL);
                        if (pedid != NULL) {
-                               par->EDID = pedid;
+                               par->EDID = (unsigned char *)pedid;
                                NVTRACE("LCD found.\n");
                                return 1;
                        }
index be40968f899e42ce0f9e7e54eebab337ca1ae92d..f3f8a8e15012af2f7544a56eec2945a9032e3055 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s3c2410fb.h
+ * linux/drivers/video/s3c2410fb.h
  * Copyright (c) Arnaud Patard
  *
  * This file is subject to the terms and conditions of the GNU General Public
index 8b3d0f0c7bd540b697ae4960a1734cfb5a4ea221..27c9d05d03ef23f1280754fab152393d6995bb14 100644 (file)
@@ -21,7 +21,7 @@ config W1_CON
          There are three types of messages between w1 core and userspace:
          1. Events. They are generated each time new master or slave device found
                either due to automatic or requested search.
-         2. Userspace commands. Includes read/write and search/alarm search comamnds.
+         2. Userspace commands. Includes read/write and search/alarm search commands.
          3. Replies to userspace commands.
 
 source drivers/w1/masters/Kconfig
index 1453d2d164f7c2d5a94e5da75d41dbba9d94a66e..674cfbb83a95cf327706848b4d8a27f895d37094 100644 (file)
@@ -74,11 +74,11 @@ config EXT3_FS
        tristate "Ext3 journalling file system support"
        select JBD
        help
-         This is the journaling version of the Second extended file system
+         This is the journalling version of the Second extended file system
          (often called ext3), the de facto standard Linux file system
          (method to organize files on a storage device) for hard disks.
 
-         The journaling code included in this driver means you do not have
+         The journalling code included in this driver means you do not have
          to run e2fsck (file system checker) on your file systems after a
          crash.  The journal keeps track of any changes that were being made
          at the time the system crashed, and can ensure that your file system
@@ -143,7 +143,7 @@ config EXT3_FS_SECURITY
 config JBD
        tristate
        help
-         This is a generic journaling layer for block devices.  It is
+         This is a generic journalling layer for block devices.  It is
          currently used by the ext3 and OCFS2 file systems, but it could
          also be used to add journal support to other file systems or block
          devices such as RAID or LVM.
@@ -183,7 +183,7 @@ config REISERFS_FS
        tristate "Reiserfs support"
        help
          Stores not just filenames but the files themselves in a balanced
-         tree.  Uses journaling.
+         tree.  Uses journalling.
 
          Balanced trees are more efficient than traditional file system
          architectural foundations.
@@ -995,6 +995,18 @@ config AFFS_FS
          To compile this file system support as a module, choose M here: the
          module will be called affs.  If unsure, say N.
 
+config ECRYPT_FS
+       tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && KEYS && CRYPTO
+       help
+         Encrypted filesystem that operates on the VFS layer.  See
+         <file:Documentation/ecryptfs.txt> to learn more about
+         eCryptfs.  Userspace components are required and can be
+         obtained from <http://ecryptfs.sf.net>.
+
+         To compile this file system support as a module, choose M here: the
+         module will be called ecryptfs.
+
 config HFS_FS
        tristate "Apple Macintosh file system support (EXPERIMENTAL)"
        depends on BLOCK && EXPERIMENTAL
@@ -1032,7 +1044,7 @@ config BEFS_FS
          on files and directories, and database-like indeces on selected
          attributes. (Also note that this driver doesn't make those features
          available at this time). It is a 64 bit filesystem, so it supports
-         extremly large volumes and files.
+         extremely large volumes and files.
 
          If you use this filesystem, you should also say Y to at least one
          of the NLS (native language support) options below.
@@ -1090,7 +1102,7 @@ config JFFS_FS
        tristate "Journalling Flash File System (JFFS) support"
        depends on MTD && BLOCK
        help
-         JFFS is the Journaling Flash File System developed by Axis
+         JFFS is the Journalling Flash File System developed by Axis
          Communications in Sweden, aimed at providing a crash/powerdown-safe
          file system for disk-less embedded devices. Further information is
          available at (<http://developer.axis.com/software/jffs/>).
@@ -1260,7 +1272,7 @@ config JFFS2_CMODE_NONE
 config JFFS2_CMODE_PRIORITY
         bool "priority"
         help
-          Tries the compressors in a predefinied order and chooses the first
+          Tries the compressors in a predefined order and chooses the first
           successful one.
 
 config JFFS2_CMODE_SIZE
@@ -1365,7 +1377,7 @@ config SYSV_FS
 
          If you have floppies or hard disk partitions like that, it is likely
          that they contain binaries from those other Unix systems; in order
-         to run these binaries, you will want to install linux-abi which is a
+         to run these binaries, you will want to install linux-abi which is
          a set of kernel modules that lets you run SCO, Xenix, Wyse,
          UnixWare, Dell Unix and System V programs under Linux.  It is
          available via FTP (user: ftp) from
@@ -1950,7 +1962,7 @@ config AFS_FS
          If you say Y here, you will get an experimental Andrew File System
          driver. It currently only supports unsecured read-only AFS access.
 
-         See <file:Documentation/filesystems/afs.txt> for more intormation.
+         See <file:Documentation/filesystems/afs.txt> for more information.
 
          If unsure, say N.
 
index 819b2a93bebe55cb4cc137514872892f90fa83da..fd24d67a7cdb5e877318a828ae9eaf8df450d656 100644 (file)
@@ -75,6 +75,7 @@ obj-$(CONFIG_BFS_FS)          += bfs/
 obj-$(CONFIG_ISO9660_FS)       += isofs/
 obj-$(CONFIG_HFSPLUS_FS)       += hfsplus/ # Before hfs to find wrapped HFS+
 obj-$(CONFIG_HFS_FS)           += hfs/
+obj-$(CONFIG_ECRYPT_FS)                += ecryptfs/
 obj-$(CONFIG_VXFS_FS)          += freevxfs/
 obj-$(CONFIG_NFS_FS)           += nfs/
 obj-$(CONFIG_EXPORTFS)         += exportfs/
index 9095518e918d2eb49f0f51fcbfe80f63252aae3a..63ef1e18fb84d2f2052dc8861f5df267f23b0727 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/linux/befs_fs_types.h
+ * fs/befs/befs_fs_types.h
  *
  * Copyright (C) 2001 Will Dyson (will@cs.earlham.edu)
  *
index 5f0e1bd64feee801b65e895075fcca5972540d8f..432e515431c4ca20aa4dd1e4e87d0908676752e1 100644 (file)
@@ -269,7 +269,7 @@ A partial list of the supported mount options follows:
                (gid) mount option is specified.  For the uid (gid) of newly
                created files and directories, ie files created since 
                the last mount of the server share, the expected uid 
-               (gid) is cached as as long as the inode remains in 
+               (gid) is cached as long as the inode remains in 
                memory on the client.   Also note that permission
                checks (authorization checks) on accesses to a file occur
                at the server, but there are cases in which an administrator
@@ -375,7 +375,7 @@ A partial list of the supported mount options follows:
                the local process on newly created files, directories, and
                devices (create, mkdir, mknod).  If the CIFS Unix Extensions
                are not negotiated, for newly created files and directories
-               instead of using the default uid and gid specified on the
+               instead of using the default uid and gid specified on
                the mount, cache the new file's uid and gid locally which means
                that the uid for the file can change when the inode is
                reloaded (or the user remounts the share).
@@ -440,7 +440,7 @@ A partial list of the supported mount options follows:
                create device files and fifos in a format compatible with
                Services for Unix (SFU).  In addition retrieve bits 10-12
                of the mode via the SETFILEBITS extended attribute (as
-               SFU does).  In the future the bottom 9 bits of the mode
+               SFU does).  In the future the bottom 9 bits of the
                mode also will be emulated using queries of the security
                descriptor (ACL).
  sign           Must use packet signing (helps avoid unwanted data modification
index fc2faa44f8d185b6be9b8600a4ffb9991d5b980f..2355bddad8de12609bcc0b517a151883638c79eb 100644 (file)
@@ -291,9 +291,9 @@ struct dentry * dget_locked(struct dentry *dentry)
  * it can be unhashed only if it has no children, or if it is the root
  * of a filesystem.
  *
- * If the inode has a DCACHE_DISCONNECTED alias, then prefer
+ * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer
  * any other hashed alias over that one unless @want_discon is set,
- * in which case only return a DCACHE_DISCONNECTED alias.
+ * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias.
  */
 
 static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
@@ -309,7 +309,8 @@ static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
                prefetch(next);
                alias = list_entry(tmp, struct dentry, d_alias);
                if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
-                       if (alias->d_flags & DCACHE_DISCONNECTED)
+                       if (IS_ROOT(alias) &&
+                           (alias->d_flags & DCACHE_DISCONNECTED))
                                discon_alias = alias;
                        else if (!want_discon) {
                                __dget_locked(alias);
@@ -1004,7 +1005,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
 {
        struct dentry *new = NULL;
 
-       if (inode) {
+       if (inode && S_ISDIR(inode->i_mode)) {
                spin_lock(&dcache_lock);
                new = __d_find_alias(inode, 1);
                if (new) {
index ecf3da9edf21ab65a1a291a5edf8836dcdcaa520..e77676df6713de8ab4016d89688b2405ba89e63b 100644 (file)
@@ -252,7 +252,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
  *
  * This function removes a file or directory in debugfs that was previously
  * created with a call to another debugfs function (like
- * debufs_create_file() or variants thereof.)
+ * debugfs_create_file() or variants thereof.)
  *
  * This function is required to be called in order for the file to be
  * removed, no automatic cleanup of files will happen when a module is
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile
new file mode 100644 (file)
index 0000000..ca65624
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the Linux 2.6 eCryptfs
+#
+
+obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
+
+ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o debug.o
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
new file mode 100644 (file)
index 0000000..ed35a97
--- /dev/null
@@ -0,0 +1,1659 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *             Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/random.h>
+#include <linux/compiler.h>
+#include <linux/key.h>
+#include <linux/namei.h>
+#include <linux/crypto.h>
+#include <linux/file.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+static int
+ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+                            struct page *dst_page, int dst_offset,
+                            struct page *src_page, int src_offset, int size,
+                            unsigned char *iv);
+static int
+ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+                            struct page *dst_page, int dst_offset,
+                            struct page *src_page, int src_offset, int size,
+                            unsigned char *iv);
+
+/**
+ * ecryptfs_to_hex
+ * @dst: Buffer to take hex character representation of contents of
+ *       src; must be at least of size (src_size * 2)
+ * @src: Buffer to be converted to a hex string respresentation
+ * @src_size: number of bytes to convert
+ */
+void ecryptfs_to_hex(char *dst, char *src, size_t src_size)
+{
+       int x;
+
+       for (x = 0; x < src_size; x++)
+               sprintf(&dst[x * 2], "%.2x", (unsigned char)src[x]);
+}
+
+/**
+ * ecryptfs_from_hex
+ * @dst: Buffer to take the bytes from src hex; must be at least of
+ *       size (src_size / 2)
+ * @src: Buffer to be converted from a hex string respresentation to raw value
+ * @dst_size: size of dst buffer, or number of hex characters pairs to convert
+ */
+void ecryptfs_from_hex(char *dst, char *src, int dst_size)
+{
+       int x;
+       char tmp[3] = { 0, };
+
+       for (x = 0; x < dst_size; x++) {
+               tmp[0] = src[x * 2];
+               tmp[1] = src[x * 2 + 1];
+               dst[x] = (unsigned char)simple_strtol(tmp, NULL, 16);
+       }
+}
+
+/**
+ * ecryptfs_calculate_md5 - calculates the md5 of @src
+ * @dst: Pointer to 16 bytes of allocated memory
+ * @crypt_stat: Pointer to crypt_stat struct for the current inode
+ * @src: Data to be md5'd
+ * @len: Length of @src
+ *
+ * Uses the allocated crypto context that crypt_stat references to
+ * generate the MD5 sum of the contents of src.
+ */
+static int ecryptfs_calculate_md5(char *dst,
+                                 struct ecryptfs_crypt_stat *crypt_stat,
+                                 char *src, int len)
+{
+       int rc = 0;
+       struct scatterlist sg;
+
+       mutex_lock(&crypt_stat->cs_md5_tfm_mutex);
+       sg_init_one(&sg, (u8 *)src, len);
+       if (!crypt_stat->md5_tfm) {
+               crypt_stat->md5_tfm =
+                       crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP);
+               if (!crypt_stat->md5_tfm) {
+                       rc = -ENOMEM;
+                       ecryptfs_printk(KERN_ERR, "Error attempting to "
+                                       "allocate crypto context\n");
+                       goto out;
+               }
+       }
+       crypto_digest_init(crypt_stat->md5_tfm);
+       crypto_digest_update(crypt_stat->md5_tfm, &sg, 1);
+       crypto_digest_final(crypt_stat->md5_tfm, dst);
+       mutex_unlock(&crypt_stat->cs_md5_tfm_mutex);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_derive_iv
+ * @iv: destination for the derived iv vale
+ * @crypt_stat: Pointer to crypt_stat struct for the current inode
+ * @offset: Offset of the page whose's iv we are to derive
+ *
+ * Generate the initialization vector from the given root IV and page
+ * offset.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
+                             pgoff_t offset)
+{
+       int rc = 0;
+       char dst[MD5_DIGEST_SIZE];
+       char src[ECRYPTFS_MAX_IV_BYTES + 16];
+
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "root iv:\n");
+               ecryptfs_dump_hex(crypt_stat->root_iv, crypt_stat->iv_bytes);
+       }
+       /* TODO: It is probably secure to just cast the least
+        * significant bits of the root IV into an unsigned long and
+        * add the offset to that rather than go through all this
+        * hashing business. -Halcrow */
+       memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes);
+       memset((src + crypt_stat->iv_bytes), 0, 16);
+       snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset);
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "source:\n");
+               ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));
+       }
+       rc = ecryptfs_calculate_md5(dst, crypt_stat, src,
+                                   (crypt_stat->iv_bytes + 16));
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error attempting to compute "
+                               "MD5 while generating IV for a page\n");
+               goto out;
+       }
+       memcpy(iv, dst, crypt_stat->iv_bytes);
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "derived iv:\n");
+               ecryptfs_dump_hex(iv, crypt_stat->iv_bytes);
+       }
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_init_crypt_stat
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ *
+ * Initialize the crypt_stat structure.
+ */
+void
+ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
+       mutex_init(&crypt_stat->cs_mutex);
+       mutex_init(&crypt_stat->cs_tfm_mutex);
+       mutex_init(&crypt_stat->cs_md5_tfm_mutex);
+       ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
+}
+
+/**
+ * ecryptfs_destruct_crypt_stat
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ *
+ * Releases all memory associated with a crypt_stat struct.
+ */
+void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->tfm)
+               crypto_free_tfm(crypt_stat->tfm);
+       if (crypt_stat->md5_tfm)
+               crypto_free_tfm(crypt_stat->md5_tfm);
+       memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
+}
+
+void ecryptfs_destruct_mount_crypt_stat(
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+       if (mount_crypt_stat->global_auth_tok_key)
+               key_put(mount_crypt_stat->global_auth_tok_key);
+       if (mount_crypt_stat->global_key_tfm)
+               crypto_free_tfm(mount_crypt_stat->global_key_tfm);
+       memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
+}
+
+/**
+ * virt_to_scatterlist
+ * @addr: Virtual address
+ * @size: Size of data; should be an even multiple of the block size
+ * @sg: Pointer to scatterlist array; set to NULL to obtain only
+ *      the number of scatterlist structs required in array
+ * @sg_size: Max array size
+ *
+ * Fills in a scatterlist array with page references for a passed
+ * virtual address.
+ *
+ * Returns the number of scatterlist structs in array used
+ */
+int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
+                       int sg_size)
+{
+       int i = 0;
+       struct page *pg;
+       int offset;
+       int remainder_of_page;
+
+       while (size > 0 && i < sg_size) {
+               pg = virt_to_page(addr);
+               offset = offset_in_page(addr);
+               if (sg) {
+                       sg[i].page = pg;
+                       sg[i].offset = offset;
+               }
+               remainder_of_page = PAGE_CACHE_SIZE - offset;
+               if (size >= remainder_of_page) {
+                       if (sg)
+                               sg[i].length = remainder_of_page;
+                       addr += remainder_of_page;
+                       size -= remainder_of_page;
+               } else {
+                       if (sg)
+                               sg[i].length = size;
+                       addr += size;
+                       size = 0;
+               }
+               i++;
+       }
+       if (size > 0)
+               return -ENOMEM;
+       return i;
+}
+
+/**
+ * encrypt_scatterlist
+ * @crypt_stat: Pointer to the crypt_stat struct to initialize.
+ * @dest_sg: Destination of encrypted data
+ * @src_sg: Data to be encrypted
+ * @size: Length of data to be encrypted
+ * @iv: iv to use during encryption
+ *
+ * Returns the number of bytes encrypted; negative value on error
+ */
+static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
+                              struct scatterlist *dest_sg,
+                              struct scatterlist *src_sg, int size,
+                              unsigned char *iv)
+{
+       int rc = 0;
+
+       BUG_ON(!crypt_stat || !crypt_stat->tfm
+              || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                      ECRYPTFS_STRUCT_INITIALIZED));
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
+                               crypt_stat->key_size);
+               ecryptfs_dump_hex(crypt_stat->key,
+                                 crypt_stat->key_size);
+       }
+       /* Consider doing this once, when the file is opened */
+       mutex_lock(&crypt_stat->cs_tfm_mutex);
+       rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
+                                 crypt_stat->key_size);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
+                               rc);
+               mutex_unlock(&crypt_stat->cs_tfm_mutex);
+               rc = -EINVAL;
+               goto out;
+       }
+       ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
+       crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
+       mutex_unlock(&crypt_stat->cs_tfm_mutex);
+out:
+       return rc;
+}
+
+static void
+ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx,
+                                        int *byte_offset,
+                                        struct ecryptfs_crypt_stat *crypt_stat,
+                                        unsigned long extent_num)
+{
+       unsigned long lower_extent_num;
+       int extents_occupied_by_headers_at_front;
+       int bytes_occupied_by_headers_at_front;
+       int extent_offset;
+       int extents_per_page;
+
+       bytes_occupied_by_headers_at_front =
+               ( crypt_stat->header_extent_size
+                 * crypt_stat->num_header_extents_at_front );
+       extents_occupied_by_headers_at_front =
+               ( bytes_occupied_by_headers_at_front
+                 / crypt_stat->extent_size );
+       lower_extent_num = extents_occupied_by_headers_at_front + extent_num;
+       extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+       (*lower_page_idx) = lower_extent_num / extents_per_page;
+       extent_offset = lower_extent_num % extents_per_page;
+       (*byte_offset) = extent_offset * crypt_stat->extent_size;
+       ecryptfs_printk(KERN_DEBUG, " * crypt_stat->header_extent_size = "
+                       "[%d]\n", crypt_stat->header_extent_size);
+       ecryptfs_printk(KERN_DEBUG, " * crypt_stat->"
+                       "num_header_extents_at_front = [%d]\n",
+                       crypt_stat->num_header_extents_at_front);
+       ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_"
+                       "front = [%d]\n", extents_occupied_by_headers_at_front);
+       ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n",
+                       lower_extent_num);
+       ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n",
+                       extents_per_page);
+       ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n",
+                       (*lower_page_idx));
+       ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n",
+                       extent_offset);
+       ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n",
+                       (*byte_offset));
+}
+
+static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx,
+                                  struct page *lower_page,
+                                  struct inode *lower_inode,
+                                  int byte_offset_in_page, int bytes_to_write)
+{
+       int rc = 0;
+
+       if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
+               rc = ecryptfs_commit_lower_page(lower_page, lower_inode,
+                                               ctx->param.lower_file,
+                                               byte_offset_in_page,
+                                               bytes_to_write);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error calling lower "
+                                       "commit; rc = [%d]\n", rc);
+                       goto out;
+               }
+       } else {
+               rc = ecryptfs_writepage_and_release_lower_page(lower_page,
+                                                              lower_inode,
+                                                              ctx->param.wbc);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error calling lower "
+                                       "writepage(); rc = [%d]\n", rc);
+                       goto out;
+               }
+       }
+out:
+       return rc;
+}
+
+static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx,
+                                struct page **lower_page,
+                                struct inode *lower_inode,
+                                unsigned long lower_page_idx,
+                                int byte_offset_in_page)
+{
+       int rc = 0;
+
+       if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
+               /* TODO: Limit this to only the data extents that are
+                * needed */
+               rc = ecryptfs_get_lower_page(lower_page, lower_inode,
+                                            ctx->param.lower_file,
+                                            lower_page_idx,
+                                            byte_offset_in_page,
+                                            (PAGE_CACHE_SIZE
+                                             - byte_offset_in_page));
+               if (rc) {
+                       ecryptfs_printk(
+                               KERN_ERR, "Error attempting to grab, map, "
+                               "and prepare_write lower page with index "
+                               "[0x%.16x]; rc = [%d]\n", lower_page_idx, rc);
+                       goto out;
+               }
+       } else {
+               rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL,
+                                                     lower_inode,
+                                                     lower_page_idx);
+               if (rc) {
+                       ecryptfs_printk(
+                               KERN_ERR, "Error attempting to grab and map "
+                               "lower page with index [0x%.16x]; rc = [%d]\n",
+                               lower_page_idx, rc);
+                       goto out;
+               }
+       }
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_encrypt_page
+ * @ctx: The context of the page
+ *
+ * Encrypt an eCryptfs page. This is done on a per-extent basis. Note
+ * that eCryptfs pages may straddle the lower pages -- for instance,
+ * if the file was created on a machine with an 8K page size
+ * (resulting in an 8K header), and then the file is copied onto a
+ * host with a 32K page size, then when reading page 0 of the eCryptfs
+ * file, 24K of page 0 of the lower file will be read and decrypted,
+ * and then 8K of page 1 of the lower file will be read and decrypted.
+ *
+ * The actual operations performed on each page depends on the
+ * contents of the ecryptfs_page_crypt_context struct.
+ *
+ * Returns zero on success; negative on error
+ */
+int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx)
+{
+       char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+       unsigned long base_extent;
+       unsigned long extent_offset = 0;
+       unsigned long lower_page_idx = 0;
+       unsigned long prior_lower_page_idx = 0;
+       struct page *lower_page;
+       struct inode *lower_inode;
+       struct ecryptfs_inode_info *inode_info;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       int rc = 0;
+       int lower_byte_offset = 0;
+       int orig_byte_offset = 0;
+       int num_extents_per_page;
+#define ECRYPTFS_PAGE_STATE_UNREAD    0
+#define ECRYPTFS_PAGE_STATE_READ      1
+#define ECRYPTFS_PAGE_STATE_MODIFIED  2
+#define ECRYPTFS_PAGE_STATE_WRITTEN   3
+       int page_state;
+
+       lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host);
+       inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host);
+       crypt_stat = &inode_info->crypt_stat;
+       if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+               rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode,
+                                                ctx->param.lower_file);
+               if (rc)
+                       ecryptfs_printk(KERN_ERR, "Error attempting to copy "
+                                       "page at index [0x%.16x]\n",
+                                       ctx->page->index);
+               goto out;
+       }
+       num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+       base_extent = (ctx->page->index * num_extents_per_page);
+       page_state = ECRYPTFS_PAGE_STATE_UNREAD;
+       while (extent_offset < num_extents_per_page) {
+               ecryptfs_extent_to_lwr_pg_idx_and_offset(
+                       &lower_page_idx, &lower_byte_offset, crypt_stat,
+                       (base_extent + extent_offset));
+               if (prior_lower_page_idx != lower_page_idx
+                   && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) {
+                       rc = ecryptfs_write_out_page(ctx, lower_page,
+                                                    lower_inode,
+                                                    orig_byte_offset,
+                                                    (PAGE_CACHE_SIZE
+                                                     - orig_byte_offset));
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "Error attempting "
+                                               "to write out page; rc = [%d]"
+                                               "\n", rc);
+                               goto out;
+                       }
+                       page_state = ECRYPTFS_PAGE_STATE_WRITTEN;
+               }
+               if (page_state == ECRYPTFS_PAGE_STATE_UNREAD
+                   || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) {
+                       rc = ecryptfs_read_in_page(ctx, &lower_page,
+                                                  lower_inode, lower_page_idx,
+                                                  lower_byte_offset);
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "Error attempting "
+                                               "to read in lower page with "
+                                               "index [0x%.16x]; rc = [%d]\n",
+                                               lower_page_idx, rc);
+                               goto out;
+                       }
+                       orig_byte_offset = lower_byte_offset;
+                       prior_lower_page_idx = lower_page_idx;
+                       page_state = ECRYPTFS_PAGE_STATE_READ;
+               }
+               BUG_ON(!(page_state == ECRYPTFS_PAGE_STATE_MODIFIED
+                        || page_state == ECRYPTFS_PAGE_STATE_READ));
+               rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+                                       (base_extent + extent_offset));
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error attempting to "
+                                       "derive IV for extent [0x%.16x]; "
+                                       "rc = [%d]\n",
+                                       (base_extent + extent_offset), rc);
+                       goto out;
+               }
+               if (unlikely(ecryptfs_verbosity > 0)) {
+                       ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
+                                       "with iv:\n");
+                       ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+                       ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+                                       "encryption:\n");
+                       ecryptfs_dump_hex((char *)
+                                         (page_address(ctx->page)
+                                          + (extent_offset
+                                             * crypt_stat->extent_size)), 8);
+               }
+               rc = ecryptfs_encrypt_page_offset(
+                       crypt_stat, lower_page, lower_byte_offset, ctx->page,
+                       (extent_offset * crypt_stat->extent_size),
+                       crypt_stat->extent_size, extent_iv);
+               ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
+                               "rc = [%d]\n",
+                               (base_extent + extent_offset), rc);
+               if (unlikely(ecryptfs_verbosity > 0)) {
+                       ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+                                       "encryption:\n");
+                       ecryptfs_dump_hex((char *)(page_address(lower_page)
+                                                  + lower_byte_offset), 8);
+               }
+               page_state = ECRYPTFS_PAGE_STATE_MODIFIED;
+               extent_offset++;
+       }
+       BUG_ON(orig_byte_offset != 0);
+       rc = ecryptfs_write_out_page(ctx, lower_page, lower_inode, 0,
+                                    (lower_byte_offset
+                                     + crypt_stat->extent_size));
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error attempting to write out "
+                               "page; rc = [%d]\n", rc);
+                               goto out;
+       }
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_decrypt_page
+ * @file: The ecryptfs file
+ * @page: The page in ecryptfs to decrypt
+ *
+ * Decrypt an eCryptfs page. This is done on a per-extent basis. Note
+ * that eCryptfs pages may straddle the lower pages -- for instance,
+ * if the file was created on a machine with an 8K page size
+ * (resulting in an 8K header), and then the file is copied onto a
+ * host with a 32K page size, then when reading page 0 of the eCryptfs
+ * file, 24K of page 0 of the lower file will be read and decrypted,
+ * and then 8K of page 1 of the lower file will be read and decrypted.
+ *
+ * Returns zero on success; negative on error
+ */
+int ecryptfs_decrypt_page(struct file *file, struct page *page)
+{
+       char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+       unsigned long base_extent;
+       unsigned long extent_offset = 0;
+       unsigned long lower_page_idx = 0;
+       unsigned long prior_lower_page_idx = 0;
+       struct page *lower_page;
+       char *lower_page_virt = NULL;
+       struct inode *lower_inode;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       int rc = 0;
+       int byte_offset;
+       int num_extents_per_page;
+       int page_state;
+
+       crypt_stat = &(ecryptfs_inode_to_private(
+                              page->mapping->host)->crypt_stat);
+       lower_inode = ecryptfs_inode_to_lower(page->mapping->host);
+       if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) {
+               rc = ecryptfs_do_readpage(file, page, page->index);
+               if (rc)
+                       ecryptfs_printk(KERN_ERR, "Error attempting to copy "
+                                       "page at index [0x%.16x]\n",
+                                       page->index);
+               goto out;
+       }
+       num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
+       base_extent = (page->index * num_extents_per_page);
+       lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache,
+                                          SLAB_KERNEL);
+       if (!lower_page_virt) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Error getting page for encrypted "
+                               "lower page(s)\n");
+               goto out;
+       }
+       lower_page = virt_to_page(lower_page_virt);
+       page_state = ECRYPTFS_PAGE_STATE_UNREAD;
+       while (extent_offset < num_extents_per_page) {
+               ecryptfs_extent_to_lwr_pg_idx_and_offset(
+                       &lower_page_idx, &byte_offset, crypt_stat,
+                       (base_extent + extent_offset));
+               if (prior_lower_page_idx != lower_page_idx
+                   || page_state == ECRYPTFS_PAGE_STATE_UNREAD) {
+                       rc = ecryptfs_do_readpage(file, lower_page,
+                                                 lower_page_idx);
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "Error reading "
+                                               "lower encrypted page; rc = "
+                                               "[%d]\n", rc);
+                               goto out;
+                       }
+                       prior_lower_page_idx = lower_page_idx;
+                       page_state = ECRYPTFS_PAGE_STATE_READ;
+               }
+               rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+                                       (base_extent + extent_offset));
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error attempting to "
+                                       "derive IV for extent [0x%.16x]; rc = "
+                                       "[%d]\n",
+                                       (base_extent + extent_offset), rc);
+                       goto out;
+               }
+               if (unlikely(ecryptfs_verbosity > 0)) {
+                       ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
+                                       "with iv:\n");
+                       ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+                       ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+                                       "decryption:\n");
+                       ecryptfs_dump_hex((lower_page_virt + byte_offset), 8);
+               }
+               rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
+                                                 (extent_offset
+                                                  * crypt_stat->extent_size),
+                                                 lower_page, byte_offset,
+                                                 crypt_stat->extent_size,
+                                                 extent_iv);
+               if (rc != crypt_stat->extent_size) {
+                       ecryptfs_printk(KERN_ERR, "Error attempting to "
+                                       "decrypt extent [0x%.16x]\n",
+                                       (base_extent + extent_offset));
+                       goto out;
+               }
+               rc = 0;
+               if (unlikely(ecryptfs_verbosity > 0)) {
+                       ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+                                       "decryption:\n");
+                       ecryptfs_dump_hex((char *)(page_address(page)
+                                                  + byte_offset), 8);
+               }
+               extent_offset++;
+       }
+out:
+       if (lower_page_virt)
+               kmem_cache_free(ecryptfs_lower_page_cache, lower_page_virt);
+       return rc;
+}
+
+/**
+ * decrypt_scatterlist
+ *
+ * Returns the number of bytes decrypted; negative value on error
+ */
+static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
+                              struct scatterlist *dest_sg,
+                              struct scatterlist *src_sg, int size,
+                              unsigned char *iv)
+{
+       int rc = 0;
+
+       /* Consider doing this once, when the file is opened */
+       mutex_lock(&crypt_stat->cs_tfm_mutex);
+       rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
+                                 crypt_stat->key_size);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
+                               rc);
+               mutex_unlock(&crypt_stat->cs_tfm_mutex);
+               rc = -EINVAL;
+               goto out;
+       }
+       ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
+       rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
+                                     iv);
+       mutex_unlock(&crypt_stat->cs_tfm_mutex);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
+                               rc);
+               goto out;
+       }
+       rc = size;
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_encrypt_page_offset
+ *
+ * Returns the number of bytes encrypted
+ */
+static int
+ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+                            struct page *dst_page, int dst_offset,
+                            struct page *src_page, int src_offset, int size,
+                            unsigned char *iv)
+{
+       struct scatterlist src_sg, dst_sg;
+
+       src_sg.page = src_page;
+       src_sg.offset = src_offset;
+       src_sg.length = size;
+       dst_sg.page = dst_page;
+       dst_sg.offset = dst_offset;
+       dst_sg.length = size;
+       return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+}
+
+/**
+ * ecryptfs_decrypt_page_offset
+ *
+ * Returns the number of bytes decrypted
+ */
+static int
+ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
+                            struct page *dst_page, int dst_offset,
+                            struct page *src_page, int src_offset, int size,
+                            unsigned char *iv)
+{
+       struct scatterlist src_sg, dst_sg;
+
+       src_sg.page = src_page;
+       src_sg.offset = src_offset;
+       src_sg.length = size;
+       dst_sg.page = dst_page;
+       dst_sg.offset = dst_offset;
+       dst_sg.length = size;
+       return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
+}
+
+#define ECRYPTFS_MAX_SCATTERLIST_LEN 4
+
+/**
+ * ecryptfs_init_crypt_ctx
+ * @crypt_stat: Uninitilized crypt stats structure
+ *
+ * Initialize the crypto context.
+ *
+ * TODO: Performance: Keep a cache of initialized cipher contexts;
+ * only init if needed
+ */
+int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       int rc = -EINVAL;
+
+       if (!crypt_stat->cipher) {
+               ecryptfs_printk(KERN_ERR, "No cipher specified\n");
+               goto out;
+       }
+       ecryptfs_printk(KERN_DEBUG,
+                       "Initializing cipher [%s]; strlen = [%d]; "
+                       "key_size_bits = [%d]\n",
+                       crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
+                       crypt_stat->key_size << 3);
+       if (crypt_stat->tfm) {
+               rc = 0;
+               goto out;
+       }
+       mutex_lock(&crypt_stat->cs_tfm_mutex);
+       crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
+                                          ECRYPTFS_DEFAULT_CHAINING_MODE
+                                          | CRYPTO_TFM_REQ_WEAK_KEY);
+       mutex_unlock(&crypt_stat->cs_tfm_mutex);
+       if (!crypt_stat->tfm) {
+               ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
+                               "Error initializing cipher [%s]\n",
+                               crypt_stat->cipher);
+               goto out;
+       }
+       rc = 0;
+out:
+       return rc;
+}
+
+static void set_extent_mask_and_shift(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       int extent_size_tmp;
+
+       crypt_stat->extent_mask = 0xFFFFFFFF;
+       crypt_stat->extent_shift = 0;
+       if (crypt_stat->extent_size == 0)
+               return;
+       extent_size_tmp = crypt_stat->extent_size;
+       while ((extent_size_tmp & 0x01) == 0) {
+               extent_size_tmp >>= 1;
+               crypt_stat->extent_mask <<= 1;
+               crypt_stat->extent_shift++;
+       }
+}
+
+void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       /* Default values; may be overwritten as we are parsing the
+        * packets. */
+       crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
+       set_extent_mask_and_shift(crypt_stat);
+       crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
+       if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+               crypt_stat->header_extent_size =
+                       ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+       } else
+               crypt_stat->header_extent_size = PAGE_CACHE_SIZE;
+       crypt_stat->num_header_extents_at_front = 1;
+}
+
+/**
+ * ecryptfs_compute_root_iv
+ * @crypt_stats
+ *
+ * On error, sets the root IV to all 0's.
+ */
+int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       int rc = 0;
+       char dst[MD5_DIGEST_SIZE];
+
+       BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE);
+       BUG_ON(crypt_stat->iv_bytes <= 0);
+       if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID)) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_WARNING, "Session key not valid; "
+                               "cannot generate root IV\n");
+               goto out;
+       }
+       rc = ecryptfs_calculate_md5(dst, crypt_stat, crypt_stat->key,
+                                   crypt_stat->key_size);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error attempting to compute "
+                               "MD5 while generating root IV\n");
+               goto out;
+       }
+       memcpy(crypt_stat->root_iv, dst, crypt_stat->iv_bytes);
+out:
+       if (rc) {
+               memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes);
+               ECRYPTFS_SET_FLAG(crypt_stat->flags,
+                                 ECRYPTFS_SECURITY_WARNING);
+       }
+       return rc;
+}
+
+static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       get_random_bytes(crypt_stat->key, crypt_stat->key_size);
+       ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+       ecryptfs_compute_root_iv(crypt_stat);
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
+               ecryptfs_dump_hex(crypt_stat->key,
+                                 crypt_stat->key_size);
+       }
+}
+
+/**
+ * ecryptfs_set_default_crypt_stat_vals
+ * @crypt_stat
+ *
+ * Default values in the event that policy does not override them.
+ */
+static void ecryptfs_set_default_crypt_stat_vals(
+       struct ecryptfs_crypt_stat *crypt_stat,
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+       ecryptfs_set_default_sizes(crypt_stat);
+       strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
+       crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
+       ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+       crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
+       crypt_stat->mount_crypt_stat = mount_crypt_stat;
+}
+
+/**
+ * ecryptfs_new_file_context
+ * @ecryptfs_dentry
+ *
+ * If the crypto context for the file has not yet been established,
+ * this is where we do that.  Establishing a new crypto context
+ * involves the following decisions:
+ *  - What cipher to use?
+ *  - What set of authentication tokens to use?
+ * Here we just worry about getting enough information into the
+ * authentication tokens so that we know that they are available.
+ * We associate the available authentication tokens with the new file
+ * via the set of signatures in the crypt_stat struct.  Later, when
+ * the headers are actually written out, we may again defer to
+ * userspace to perform the encryption of the session key; for the
+ * foreseeable future, this will be the case with public key packets.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+/* Associate an authentication token(s) with the file */
+int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
+{
+       int rc = 0;
+       struct ecryptfs_crypt_stat *crypt_stat =
+           &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+           &ecryptfs_superblock_to_private(
+                   ecryptfs_dentry->d_sb)->mount_crypt_stat;
+       int cipher_name_len;
+
+       ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat);
+       /* See if there are mount crypt options */
+       if (mount_crypt_stat->global_auth_tok) {
+               ecryptfs_printk(KERN_DEBUG, "Initializing context for new "
+                               "file using mount_crypt_stat\n");
+               ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+               ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+               memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++],
+                      mount_crypt_stat->global_auth_tok_sig,
+                      ECRYPTFS_SIG_SIZE_HEX);
+               cipher_name_len =
+                   strlen(mount_crypt_stat->global_default_cipher_name);
+               memcpy(crypt_stat->cipher,
+                      mount_crypt_stat->global_default_cipher_name,
+                      cipher_name_len);
+               crypt_stat->cipher[cipher_name_len] = '\0';
+               crypt_stat->key_size =
+                       mount_crypt_stat->global_default_cipher_key_size;
+               ecryptfs_generate_new_key(crypt_stat);
+       } else
+               /* We should not encounter this scenario since we
+                * should detect lack of global_auth_tok at mount time
+                * TODO: Applies to 0.1 release only; remove in future
+                * release */
+               BUG();
+       rc = ecryptfs_init_crypt_ctx(crypt_stat);
+       if (rc)
+               ecryptfs_printk(KERN_ERR, "Error initializing cryptographic "
+                               "context for cipher [%s]: rc = [%d]\n",
+                               crypt_stat->cipher, rc);
+       return rc;
+}
+
+/**
+ * contains_ecryptfs_marker - check for the ecryptfs marker
+ * @data: The data block in which to check
+ *
+ * Returns one if marker found; zero if not found
+ */
+int contains_ecryptfs_marker(char *data)
+{
+       u32 m_1, m_2;
+
+       memcpy(&m_1, data, 4);
+       m_1 = be32_to_cpu(m_1);
+       memcpy(&m_2, (data + 4), 4);
+       m_2 = be32_to_cpu(m_2);
+       if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
+               return 1;
+       ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; "
+                       "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2,
+                       MAGIC_ECRYPTFS_MARKER);
+       ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = "
+                       "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER));
+       return 0;
+}
+
+struct ecryptfs_flag_map_elem {
+       u32 file_flag;
+       u32 local_flag;
+};
+
+/* Add support for additional flags by adding elements here. */
+static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
+       {0x00000001, ECRYPTFS_ENABLE_HMAC},
+       {0x00000002, ECRYPTFS_ENCRYPTED}
+};
+
+/**
+ * ecryptfs_process_flags
+ * @crypt_stat
+ * @page_virt: Source data to be parsed
+ * @bytes_read: Updated with the number of bytes read
+ *
+ * Returns zero on success; non-zero if the flag set is invalid
+ */
+static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat,
+                                 char *page_virt, int *bytes_read)
+{
+       int rc = 0;
+       int i;
+       u32 flags;
+
+       memcpy(&flags, page_virt, 4);
+       flags = be32_to_cpu(flags);
+       for (i = 0; i < ((sizeof(ecryptfs_flag_map)
+                         / sizeof(struct ecryptfs_flag_map_elem))); i++)
+               if (flags & ecryptfs_flag_map[i].file_flag) {
+                       ECRYPTFS_SET_FLAG(crypt_stat->flags,
+                                         ecryptfs_flag_map[i].local_flag);
+               } else
+                       ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
+                                           ecryptfs_flag_map[i].local_flag);
+       /* Version is in top 8 bits of the 32-bit flag vector */
+       crypt_stat->file_version = ((flags >> 24) & 0xFF);
+       (*bytes_read) = 4;
+       return rc;
+}
+
+/**
+ * write_ecryptfs_marker
+ * @page_virt: The pointer to in a page to begin writing the marker
+ * @written: Number of bytes written
+ *
+ * Marker = 0x3c81b7f5
+ */
+static void write_ecryptfs_marker(char *page_virt, size_t *written)
+{
+       u32 m_1, m_2;
+
+       get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+       m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER);
+       m_1 = cpu_to_be32(m_1);
+       memcpy(page_virt, &m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+       m_2 = cpu_to_be32(m_2);
+       memcpy(page_virt + (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2), &m_2,
+              (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+       (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
+}
+
+static void
+write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
+                    size_t *written)
+{
+       u32 flags = 0;
+       int i;
+
+       for (i = 0; i < ((sizeof(ecryptfs_flag_map)
+                         / sizeof(struct ecryptfs_flag_map_elem))); i++)
+               if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                       ecryptfs_flag_map[i].local_flag))
+                       flags |= ecryptfs_flag_map[i].file_flag;
+       /* Version is in top 8 bits of the 32-bit flag vector */
+       flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000);
+       flags = cpu_to_be32(flags);
+       memcpy(page_virt, &flags, 4);
+       (*written) = 4;
+}
+
+struct ecryptfs_cipher_code_str_map_elem {
+       char cipher_str[16];
+       u16 cipher_code;
+};
+
+/* Add support for additional ciphers by adding elements here. The
+ * cipher_code is whatever OpenPGP applicatoins use to identify the
+ * ciphers. List in order of probability. */
+static struct ecryptfs_cipher_code_str_map_elem
+ecryptfs_cipher_code_str_map[] = {
+       {"aes",RFC2440_CIPHER_AES_128 },
+       {"blowfish", RFC2440_CIPHER_BLOWFISH},
+       {"des3_ede", RFC2440_CIPHER_DES3_EDE},
+       {"cast5", RFC2440_CIPHER_CAST_5},
+       {"twofish", RFC2440_CIPHER_TWOFISH},
+       {"cast6", RFC2440_CIPHER_CAST_6},
+       {"aes", RFC2440_CIPHER_AES_192},
+       {"aes", RFC2440_CIPHER_AES_256}
+};
+
+/**
+ * ecryptfs_code_for_cipher_string
+ * @str: The string representing the cipher name
+ *
+ * Returns zero on no match, or the cipher code on match
+ */
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       int i;
+       u16 code = 0;
+       struct ecryptfs_cipher_code_str_map_elem *map =
+               ecryptfs_cipher_code_str_map;
+
+       if (strcmp(crypt_stat->cipher, "aes") == 0) {
+               switch (crypt_stat->key_size) {
+               case 16:
+                       code = RFC2440_CIPHER_AES_128;
+                       break;
+               case 24:
+                       code = RFC2440_CIPHER_AES_192;
+                       break;
+               case 32:
+                       code = RFC2440_CIPHER_AES_256;
+               }
+       } else {
+               for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++)
+                       if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){
+                               code = map[i].cipher_code;
+                               break;
+                       }
+       }
+       return code;
+}
+
+/**
+ * ecryptfs_cipher_code_to_string
+ * @str: Destination to write out the cipher name
+ * @cipher_code: The code to convert to cipher name string
+ *
+ * Returns zero on success
+ */
+int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
+{
+       int rc = 0;
+       int i;
+
+       str[0] = '\0';
+       for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++)
+               if (cipher_code == ecryptfs_cipher_code_str_map[i].cipher_code)
+                       strcpy(str, ecryptfs_cipher_code_str_map[i].cipher_str);
+       if (str[0] == '\0') {
+               ecryptfs_printk(KERN_WARNING, "Cipher code not recognized: "
+                               "[%d]\n", cipher_code);
+               rc = -EINVAL;
+       }
+       return rc;
+}
+
+/**
+ * ecryptfs_read_header_region
+ * @data
+ * @dentry
+ * @nd
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_read_header_region(char *data, struct dentry *dentry,
+                               struct vfsmount *mnt)
+{
+       struct file *file;
+       mm_segment_t oldfs;
+       int rc;
+
+       mnt = mntget(mnt);
+       file = dentry_open(dentry, mnt, O_RDONLY);
+       if (IS_ERR(file)) {
+               ecryptfs_printk(KERN_DEBUG, "Error opening file to "
+                               "read header region\n");
+               mntput(mnt);
+               rc = PTR_ERR(file);
+               goto out;
+       }
+       file->f_pos = 0;
+       oldfs = get_fs();
+       set_fs(get_ds());
+       /* For releases 0.1 and 0.2, all of the header information
+        * fits in the first data extent-sized region. */
+       rc = file->f_op->read(file, (char __user *)data,
+                             ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos);
+       set_fs(oldfs);
+       fput(file);
+       rc = 0;
+out:
+       return rc;
+}
+
+static void
+write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat,
+                     size_t *written)
+{
+       u32 header_extent_size;
+       u16 num_header_extents_at_front;
+
+       header_extent_size = (u32)crypt_stat->header_extent_size;
+       num_header_extents_at_front =
+               (u16)crypt_stat->num_header_extents_at_front;
+       header_extent_size = cpu_to_be32(header_extent_size);
+       memcpy(virt, &header_extent_size, 4);
+       virt += 4;
+       num_header_extents_at_front = cpu_to_be16(num_header_extents_at_front);
+       memcpy(virt, &num_header_extents_at_front, 2);
+       (*written) = 6;
+}
+
+struct kmem_cache *ecryptfs_header_cache_0;
+struct kmem_cache *ecryptfs_header_cache_1;
+struct kmem_cache *ecryptfs_header_cache_2;
+
+/**
+ * ecryptfs_write_headers_virt
+ * @page_virt
+ * @crypt_stat
+ * @ecryptfs_dentry
+ *
+ * Format version: 1
+ *
+ *   Header Extent:
+ *     Octets 0-7:        Unencrypted file size (big-endian)
+ *     Octets 8-15:       eCryptfs special marker
+ *     Octets 16-19:      Flags
+ *      Octet 16:         File format version number (between 0 and 255)
+ *      Octets 17-18:     Reserved
+ *      Octet 19:         Bit 1 (lsb): Reserved
+ *                        Bit 2: Encrypted?
+ *                        Bits 3-8: Reserved
+ *     Octets 20-23:      Header extent size (big-endian)
+ *     Octets 24-25:      Number of header extents at front of file
+ *                        (big-endian)
+ *     Octet  26:         Begin RFC 2440 authentication token packet set
+ *   Data Extent 0:
+ *     Lower data (CBC encrypted)
+ *   Data Extent 1:
+ *     Lower data (CBC encrypted)
+ *   ...
+ *
+ * Returns zero on success
+ */
+int ecryptfs_write_headers_virt(char *page_virt,
+                               struct ecryptfs_crypt_stat *crypt_stat,
+                               struct dentry *ecryptfs_dentry)
+{
+       int rc;
+       size_t written;
+       size_t offset;
+
+       offset = ECRYPTFS_FILE_SIZE_BYTES;
+       write_ecryptfs_marker((page_virt + offset), &written);
+       offset += written;
+       write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+       offset += written;
+       write_header_metadata((page_virt + offset), crypt_stat, &written);
+       offset += written;
+       rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat,
+                                             ecryptfs_dentry, &written,
+                                             PAGE_CACHE_SIZE - offset);
+       if (rc)
+               ecryptfs_printk(KERN_WARNING, "Error generating key packet "
+                               "set; rc = [%d]\n", rc);
+       return rc;
+}
+
+/**
+ * ecryptfs_write_headers
+ * @lower_file: The lower file struct, which was returned from dentry_open
+ *
+ * Write the file headers out.  This will likely involve a userspace
+ * callout, in which the session key is encrypted with one or more
+ * public keys and/or the passphrase necessary to do the encryption is
+ * retrieved via a prompt.  Exactly what happens at this point should
+ * be policy-dependent.
+ *
+ * Returns zero on success; non-zero on error
+ */
+int ecryptfs_write_headers(struct dentry *ecryptfs_dentry,
+                          struct file *lower_file)
+{
+       mm_segment_t oldfs;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       char *page_virt;
+       int current_header_page;
+       int header_pages;
+       int rc = 0;
+
+       crypt_stat = &ecryptfs_inode_to_private(
+               ecryptfs_dentry->d_inode)->crypt_stat;
+       if (likely(ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                      ECRYPTFS_ENCRYPTED))) {
+               if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                        ECRYPTFS_KEY_VALID)) {
+                       ecryptfs_printk(KERN_DEBUG, "Key is "
+                                       "invalid; bailing out\n");
+                       rc = -EINVAL;
+                       goto out;
+               }
+       } else {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_WARNING,
+                               "Called with crypt_stat->encrypted == 0\n");
+               goto out;
+       }
+       /* Released in this function */
+       page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER);
+       if (!page_virt) {
+               ecryptfs_printk(KERN_ERR, "Out of memory\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       memset(page_virt, 0, PAGE_CACHE_SIZE);
+       rc = ecryptfs_write_headers_virt(page_virt, crypt_stat,
+                                        ecryptfs_dentry);
+       if (unlikely(rc)) {
+               ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n");
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
+               goto out_free;
+       }
+       ecryptfs_printk(KERN_DEBUG,
+                       "Writing key packet set to underlying file\n");
+       lower_file->f_pos = 0;
+       oldfs = get_fs();
+       set_fs(get_ds());
+       ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->"
+                       "write() w/ header page; lower_file->f_pos = "
+                       "[0x%.16x]\n", lower_file->f_pos);
+       lower_file->f_op->write(lower_file, (char __user *)page_virt,
+                               PAGE_CACHE_SIZE, &lower_file->f_pos);
+       header_pages = ((crypt_stat->header_extent_size
+                        * crypt_stat->num_header_extents_at_front)
+                       / PAGE_CACHE_SIZE);
+       memset(page_virt, 0, PAGE_CACHE_SIZE);
+       current_header_page = 1;
+       while (current_header_page < header_pages) {
+               ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->"
+                               "write() w/ zero'd page; lower_file->f_pos = "
+                               "[0x%.16x]\n", lower_file->f_pos);
+               lower_file->f_op->write(lower_file, (char __user *)page_virt,
+                                       PAGE_CACHE_SIZE, &lower_file->f_pos);
+               current_header_page++;
+       }
+       set_fs(oldfs);
+       ecryptfs_printk(KERN_DEBUG,
+                       "Done writing key packet set to underlying file.\n");
+out_free:
+       kmem_cache_free(ecryptfs_header_cache_0, page_virt);
+out:
+       return rc;
+}
+
+static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
+                                char *virt, int *bytes_read)
+{
+       int rc = 0;
+       u32 header_extent_size;
+       u16 num_header_extents_at_front;
+
+       memcpy(&header_extent_size, virt, 4);
+       header_extent_size = be32_to_cpu(header_extent_size);
+       virt += 4;
+       memcpy(&num_header_extents_at_front, virt, 2);
+       num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
+       crypt_stat->header_extent_size = (int)header_extent_size;
+       crypt_stat->num_header_extents_at_front =
+               (int)num_header_extents_at_front;
+       (*bytes_read) = 6;
+       if ((crypt_stat->header_extent_size
+            * crypt_stat->num_header_extents_at_front)
+           < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_WARNING, "Invalid header extent size: "
+                               "[%d]\n", crypt_stat->header_extent_size);
+       }
+       return rc;
+}
+
+/**
+ * set_default_header_data
+ *
+ * For version 0 file format; this function is only for backwards
+ * compatibility for files created with the prior versions of
+ * eCryptfs.
+ */
+static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       crypt_stat->header_extent_size = 4096;
+       crypt_stat->num_header_extents_at_front = 1;
+}
+
+/**
+ * ecryptfs_read_headers_virt
+ *
+ * Read/parse the header data. The header format is detailed in the
+ * comment block for the ecryptfs_write_headers_virt() function.
+ *
+ * Returns zero on success
+ */
+static int ecryptfs_read_headers_virt(char *page_virt,
+                                     struct ecryptfs_crypt_stat *crypt_stat,
+                                     struct dentry *ecryptfs_dentry)
+{
+       int rc = 0;
+       int offset;
+       int bytes_read;
+
+       ecryptfs_set_default_sizes(crypt_stat);
+       crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private(
+               ecryptfs_dentry->d_sb)->mount_crypt_stat;
+       offset = ECRYPTFS_FILE_SIZE_BYTES;
+       rc = contains_ecryptfs_marker(page_virt + offset);
+       if (rc == 0) {
+               rc = -EINVAL;
+               goto out;
+       }
+       offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
+       rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
+                                   &bytes_read);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error processing flags\n");
+               goto out;
+       }
+       if (crypt_stat->file_version > ECRYPTFS_SUPPORTED_FILE_VERSION) {
+               ecryptfs_printk(KERN_WARNING, "File version is [%d]; only "
+                               "file version [%d] is supported by this "
+                               "version of eCryptfs\n",
+                               crypt_stat->file_version,
+                               ECRYPTFS_SUPPORTED_FILE_VERSION);
+               rc = -EINVAL;
+               goto out;
+       }
+       offset += bytes_read;
+       if (crypt_stat->file_version >= 1) {
+               rc = parse_header_metadata(crypt_stat, (page_virt + offset),
+                                          &bytes_read);
+               if (rc) {
+                       ecryptfs_printk(KERN_WARNING, "Error reading header "
+                                       "metadata; rc = [%d]\n", rc);
+               }
+               offset += bytes_read;
+       } else
+               set_default_header_data(crypt_stat);
+       rc = ecryptfs_parse_packet_set(crypt_stat, (page_virt + offset),
+                                      ecryptfs_dentry);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_read_headers
+ *
+ * Returns zero if valid headers found and parsed; non-zero otherwise
+ */
+int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
+                         struct file *lower_file)
+{
+       int rc = 0;
+       char *page_virt = NULL;
+       mm_segment_t oldfs;
+       ssize_t bytes_read;
+       struct ecryptfs_crypt_stat *crypt_stat =
+           &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+
+       /* Read the first page from the underlying file */
+       page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER);
+       if (!page_virt) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n");
+               goto out;
+       }
+       lower_file->f_pos = 0;
+       oldfs = get_fs();
+       set_fs(get_ds());
+       bytes_read = lower_file->f_op->read(lower_file,
+                                           (char __user *)page_virt,
+                                           ECRYPTFS_DEFAULT_EXTENT_SIZE,
+                                           &lower_file->f_pos);
+       set_fs(oldfs);
+       if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) {
+               rc = -EINVAL;
+               goto out;
+       }
+       rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
+                                       ecryptfs_dentry);
+       if (rc) {
+               ecryptfs_printk(KERN_DEBUG, "Valid eCryptfs headers not "
+                               "found\n");
+               rc = -EINVAL;
+       }
+out:
+       if (page_virt) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
+               kmem_cache_free(ecryptfs_header_cache_1, page_virt);
+       }
+       return rc;
+}
+
+/**
+ * ecryptfs_encode_filename - converts a plaintext file name to cipher text
+ * @crypt_stat: The crypt_stat struct associated with the file anem to encode
+ * @name: The plaintext name
+ * @length: The length of the plaintext
+ * @encoded_name: The encypted name
+ *
+ * Encrypts and encodes a filename into something that constitutes a
+ * valid filename for a filesystem, with printable characters.
+ *
+ * We assume that we have a properly initialized crypto context,
+ * pointed to by crypt_stat->tfm.
+ *
+ * TODO: Implement filename decoding and decryption here, in place of
+ * memcpy. We are keeping the framework around for now to (1)
+ * facilitate testing of the components needed to implement filename
+ * encryption and (2) to provide a code base from which other
+ * developers in the community can easily implement this feature.
+ *
+ * Returns the length of encoded filename; negative if error
+ */
+int
+ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+                        const char *name, int length, char **encoded_name)
+{
+       int error = 0;
+
+       (*encoded_name) = kmalloc(length + 2, GFP_KERNEL);
+       if (!(*encoded_name)) {
+               error = -ENOMEM;
+               goto out;
+       }
+       /* TODO: Filename encryption is a scheduled feature for a
+        * future version of eCryptfs. This function is here only for
+        * the purpose of providing a framework for other developers
+        * to easily implement filename encryption. Hint: Replace this
+        * memcpy() with a call to encrypt and encode the
+        * filename, the set the length accordingly. */
+       memcpy((void *)(*encoded_name), (void *)name, length);
+       (*encoded_name)[length] = '\0';
+       error = length + 1;
+out:
+       return error;
+}
+
+/**
+ * ecryptfs_decode_filename - converts the cipher text name to plaintext
+ * @crypt_stat: The crypt_stat struct associated with the file
+ * @name: The filename in cipher text
+ * @length: The length of the cipher text name
+ * @decrypted_name: The plaintext name
+ *
+ * Decodes and decrypts the filename.
+ *
+ * We assume that we have a properly initialized crypto context,
+ * pointed to by crypt_stat->tfm.
+ *
+ * TODO: Implement filename decoding and decryption here, in place of
+ * memcpy. We are keeping the framework around for now to (1)
+ * facilitate testing of the components needed to implement filename
+ * encryption and (2) to provide a code base from which other
+ * developers in the community can easily implement this feature.
+ *
+ * Returns the length of decoded filename; negative if error
+ */
+int
+ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+                        const char *name, int length, char **decrypted_name)
+{
+       int error = 0;
+
+       (*decrypted_name) = kmalloc(length + 2, GFP_KERNEL);
+       if (!(*decrypted_name)) {
+               error = -ENOMEM;
+               goto out;
+       }
+       /* TODO: Filename encryption is a scheduled feature for a
+        * future version of eCryptfs. This function is here only for
+        * the purpose of providing a framework for other developers
+        * to easily implement filename encryption. Hint: Replace this
+        * memcpy() with a call to decode and decrypt the
+        * filename, the set the length accordingly. */
+       memcpy((void *)(*decrypted_name), (void *)name, length);
+       (*decrypted_name)[length + 1] = '\0';   /* Only for convenience
+                                                * in printing out the
+                                                * string in debug
+                                                * messages */
+       error = length;
+out:
+       return error;
+}
+
+/**
+ * ecryptfs_process_cipher - Perform cipher initialization.
+ * @tfm: Crypto context set by this function
+ * @key_tfm: Crypto context for key material, set by this function
+ * @cipher_name: Name of the cipher.
+ * @key_size: Size of the key in bytes.
+ *
+ * Returns zero on success. Any crypto_tfm structs allocated here
+ * should be released by other functions, such as on a superblock put
+ * event, regardless of whether this function succeeds for fails.
+ */
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+                       char *cipher_name, size_t key_size)
+{
+       char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+       int rc;
+
+       *tfm = *key_tfm = NULL;
+       if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum "
+                      "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
+               goto out;
+       }
+       *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
+                                             | CRYPTO_TFM_REQ_WEAK_KEY));
+       if (!(*tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Unable to allocate crypto cipher with name "
+                      "[%s]\n", cipher_name);
+               goto out;
+       }
+       *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
+       if (!(*key_tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Unable to allocate crypto cipher with name "
+                      "[%s]\n", cipher_name);
+               goto out;
+       }
+       if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
+                      "supported by cipher [%s] is [%d]\n", key_size,
+                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+               goto out;
+       }
+       if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
+                      "supported by cipher [%s] is [%d]\n", key_size,
+                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+               goto out;
+       }
+       if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
+                      "supported by cipher [%s] is [%d]\n", key_size,
+                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+               goto out;
+       }
+       if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
+               rc = -EINVAL;
+               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
+                      "supported by cipher [%s] is [%d]\n", key_size,
+                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+               goto out;
+       }
+       get_random_bytes(dummy_key, key_size);
+       rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
+       if (rc) {
+               printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
+                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+               rc = -EINVAL;
+               goto out;
+       }
+       rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
+       if (rc) {
+               printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
+                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+               rc = -EINVAL;
+               goto out;
+       }
+out:
+       return rc;
+}
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c
new file mode 100644 (file)
index 0000000..61f8e89
--- /dev/null
@@ -0,0 +1,123 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * Functions only useful for debugging.
+ *
+ * Copyright (C) 2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_dump_auth_tok - debug function to print auth toks
+ *
+ * This function will print the contents of an ecryptfs authentication
+ * token.
+ */
+void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok)
+{
+       char salt[ECRYPTFS_SALT_SIZE * 2 + 1];
+       char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+
+       ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n",
+                       auth_tok);
+       if (ECRYPTFS_CHECK_FLAG(auth_tok->flags, ECRYPTFS_PRIVATE_KEY)) {
+               ecryptfs_printk(KERN_DEBUG, " * private key type\n");
+               ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT "
+                               "IN ECRYPTFS VERSION 0.1)\n");
+       } else {
+               ecryptfs_printk(KERN_DEBUG, " * passphrase type\n");
+               ecryptfs_to_hex(salt, auth_tok->token.password.salt,
+                               ECRYPTFS_SALT_SIZE);
+               salt[ECRYPTFS_SALT_SIZE * 2] = '\0';
+               ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt);
+               if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
+                                       ECRYPTFS_PERSISTENT_PASSWORD)) {
+                       ecryptfs_printk(KERN_DEBUG, " * persistent\n");
+               }
+               memcpy(sig, auth_tok->token.password.signature,
+                      ECRYPTFS_SIG_SIZE_HEX);
+               sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+               ecryptfs_printk(KERN_DEBUG, " * signature = [%s]\n", sig);
+       }
+       ecryptfs_printk(KERN_DEBUG, " * session_key.flags = [0x%x]\n",
+                       auth_tok->session_key.flags);
+       if (auth_tok->session_key.flags
+           & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT)
+               ecryptfs_printk(KERN_DEBUG,
+                               " * Userspace decrypt request set\n");
+       if (auth_tok->session_key.flags
+           & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT)
+               ecryptfs_printk(KERN_DEBUG,
+                               " * Userspace encrypt request set\n");
+       if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_DECRYPTED_KEY) {
+               ecryptfs_printk(KERN_DEBUG, " * Contains decrypted key\n");
+               ecryptfs_printk(KERN_DEBUG,
+                               " * session_key.decrypted_key_size = [0x%x]\n",
+                               auth_tok->session_key.decrypted_key_size);
+               ecryptfs_printk(KERN_DEBUG, " * Decrypted session key "
+                               "dump:\n");
+               if (ecryptfs_verbosity > 0)
+                       ecryptfs_dump_hex(auth_tok->session_key.decrypted_key,
+                                         ECRYPTFS_DEFAULT_KEY_BYTES);
+       }
+       if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_ENCRYPTED_KEY) {
+               ecryptfs_printk(KERN_DEBUG, " * Contains encrypted key\n");
+               ecryptfs_printk(KERN_DEBUG,
+                               " * session_key.encrypted_key_size = [0x%x]\n",
+                               auth_tok->session_key.encrypted_key_size);
+               ecryptfs_printk(KERN_DEBUG, " * Encrypted session key "
+                               "dump:\n");
+               if (ecryptfs_verbosity > 0)
+                       ecryptfs_dump_hex(auth_tok->session_key.encrypted_key,
+                                         auth_tok->session_key.
+                                         encrypted_key_size);
+       }
+}
+
+/**
+ * ecryptfs_dump_hex - debug hex printer
+ * @data: string of bytes to be printed
+ * @bytes: number of bytes to print
+ *
+ * Dump hexadecimal representation of char array
+ */
+void ecryptfs_dump_hex(char *data, int bytes)
+{
+       int i = 0;
+       int add_newline = 1;
+
+       if (ecryptfs_verbosity < 1)
+               return;
+       if (bytes != 0) {
+               printk(KERN_DEBUG "0x%.2x.", (unsigned char)data[i]);
+               i++;
+       }
+       while (i < bytes) {
+               printk("0x%.2x.", (unsigned char)data[i]);
+               i++;
+               if (i % 16 == 0) {
+                       printk("\n");
+                       add_newline = 0;
+               } else
+                       add_newline = 1;
+       }
+       if (add_newline)
+               printk("\n");
+}
+
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
new file mode 100644 (file)
index 0000000..f0d2a43
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
+ * @dentry: The ecryptfs dentry
+ * @nd: The associated nameidata
+ *
+ * Called when the VFS needs to revalidate a dentry. This
+ * is called whenever a name lookup finds a dentry in the
+ * dcache. Most filesystems leave this as NULL, because all their
+ * dentries in the dcache are valid.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ *
+ */
+static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+       struct dentry *dentry_save;
+       struct vfsmount *vfsmount_save;
+       int rc = 1;
+
+       if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
+               goto out;
+       dentry_save = nd->dentry;
+       vfsmount_save = nd->mnt;
+       nd->dentry = lower_dentry;
+       nd->mnt = lower_mnt;
+       rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
+       nd->dentry = dentry_save;
+       nd->mnt = vfsmount_save;
+out:
+       return rc;
+}
+
+struct kmem_cache *ecryptfs_dentry_info_cache;
+
+/**
+ * ecryptfs_d_release
+ * @dentry: The ecryptfs dentry
+ *
+ * Called when a dentry is really deallocated.
+ */
+static void ecryptfs_d_release(struct dentry *dentry)
+{
+       struct dentry *lower_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (ecryptfs_dentry_to_private(dentry))
+               kmem_cache_free(ecryptfs_dentry_info_cache,
+                               ecryptfs_dentry_to_private(dentry));
+       if (lower_dentry)
+               dput(lower_dentry);
+       return;
+}
+
+struct dentry_operations ecryptfs_dops = {
+       .d_revalidate = ecryptfs_d_revalidate,
+       .d_release = ecryptfs_d_release,
+};
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
new file mode 100644 (file)
index 0000000..872c995
--- /dev/null
@@ -0,0 +1,482 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * Kernel declarations.
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ECRYPTFS_KERNEL_H
+#define ECRYPTFS_KERNEL_H
+
+#include <keys/user-type.h>
+#include <linux/fs.h>
+#include <linux/scatterlist.h>
+
+/* Version verification for shared data structures w/ userspace */
+#define ECRYPTFS_VERSION_MAJOR 0x00
+#define ECRYPTFS_VERSION_MINOR 0x04
+#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x01
+/* These flags indicate which features are supported by the kernel
+ * module; userspace tools such as the mount helper read
+ * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
+ * how to behave. */
+#define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001
+#define ECRYPTFS_VERSIONING_PUBKEY 0x00000002
+#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
+#define ECRYPTFS_VERSIONING_POLICY 0x00000008
+#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
+                                  | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH)
+
+#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
+#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
+#define ECRYPTFS_SALT_SIZE 8
+#define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2)
+/* The original signature size is only for what is stored on disk; all
+ * in-memory representations are expanded hex, so it better adapted to
+ * be passed around or referenced on the command line */
+#define ECRYPTFS_SIG_SIZE 8
+#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
+#define ECRYPTFS_MAX_KEY_BYTES 64
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
+#define ECRYPTFS_DEFAULT_IV_BYTES 16
+#define ECRYPTFS_FILE_VERSION 0x01
+#define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192
+#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
+#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
+
+#define RFC2440_CIPHER_DES3_EDE 0x02
+#define RFC2440_CIPHER_CAST_5 0x03
+#define RFC2440_CIPHER_BLOWFISH 0x04
+#define RFC2440_CIPHER_AES_128 0x07
+#define RFC2440_CIPHER_AES_192 0x08
+#define RFC2440_CIPHER_AES_256 0x09
+#define RFC2440_CIPHER_TWOFISH 0x0a
+#define RFC2440_CIPHER_CAST_6 0x0b
+
+#define ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag))
+#define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag))
+#define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag))
+
+/**
+ * For convenience, we may need to pass around the encrypted session
+ * key between kernel and userspace because the authentication token
+ * may not be extractable.  For example, the TPM may not release the
+ * private key, instead requiring the encrypted data and returning the
+ * decrypted data.
+ */
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
+       u32 flags;
+       u32 encrypted_key_size;
+       u32 decrypted_key_size;
+       u8 encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+       u8 decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
+};
+
+struct ecryptfs_password {
+       u32 password_bytes;
+       s32 hash_algo;
+       u32 hash_iterations;
+       u32 session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+       u32 flags;
+       /* Iterated-hash concatenation of salt and passphrase */
+       u8 session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+       u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+       /* Always in expanded hex */
+       u8 salt[ECRYPTFS_SALT_SIZE];
+};
+
+enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
+
+/* May be a password or a private key */
+struct ecryptfs_auth_tok {
+       u16 version; /* 8-bit major and 8-bit minor */
+       u16 token_type;
+       u32 flags;
+       struct ecryptfs_session_key session_key;
+       u8 reserved[32];
+       union {
+               struct ecryptfs_password password;
+               /* Private key is in future eCryptfs releases */
+       } token;
+} __attribute__ ((packed));
+
+void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok);
+extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size);
+extern void ecryptfs_from_hex(char *dst, char *src, int dst_size);
+
+struct ecryptfs_key_record {
+       unsigned char type;
+       size_t enc_key_size;
+       unsigned char sig[ECRYPTFS_SIG_SIZE];
+       unsigned char enc_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+};
+
+struct ecryptfs_auth_tok_list {
+       struct ecryptfs_auth_tok *auth_tok;
+       struct list_head list;
+};
+
+struct ecryptfs_crypt_stat;
+struct ecryptfs_mount_crypt_stat;
+
+struct ecryptfs_page_crypt_context {
+       struct page *page;
+#define ECRYPTFS_PREPARE_COMMIT_MODE 0
+#define ECRYPTFS_WRITEPAGE_MODE      1
+       unsigned int mode;
+       union {
+               struct file *lower_file;
+               struct writeback_control *wbc;
+       } param;
+};
+
+static inline struct ecryptfs_auth_tok *
+ecryptfs_get_key_payload_data(struct key *key)
+{
+       return (struct ecryptfs_auth_tok *)
+               (((struct user_key_payload*)key->payload.data)->data);
+}
+
+#define ECRYPTFS_SUPER_MAGIC 0xf15f
+#define ECRYPTFS_MAX_KEYSET_SIZE 1024
+#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32
+#define ECRYPTFS_MAX_NUM_ENC_KEYS 64
+#define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */
+#define ECRYPTFS_MAX_IV_BYTES 16       /* 128 bits */
+#define ECRYPTFS_SALT_BYTES 2
+#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5
+#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8     /* 4*2 */
+#define ECRYPTFS_FILE_SIZE_BYTES 8
+#define ECRYPTFS_DEFAULT_CIPHER "aes"
+#define ECRYPTFS_DEFAULT_KEY_BYTES 16
+#define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
+#define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
+#define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
+#define MD5_DIGEST_SIZE 16
+
+/**
+ * This is the primary struct associated with each encrypted file.
+ *
+ * TODO: cache align/pack?
+ */
+struct ecryptfs_crypt_stat {
+#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001
+#define ECRYPTFS_POLICY_APPLIED     0x00000002
+#define ECRYPTFS_NEW_FILE           0x00000004
+#define ECRYPTFS_ENCRYPTED          0x00000008
+#define ECRYPTFS_SECURITY_WARNING   0x00000010
+#define ECRYPTFS_ENABLE_HMAC        0x00000020
+#define ECRYPTFS_ENCRYPT_IV_PAGES   0x00000040
+#define ECRYPTFS_KEY_VALID          0x00000080
+       u32 flags;
+       unsigned int file_version;
+       size_t iv_bytes;
+       size_t num_keysigs;
+       size_t header_extent_size;
+       size_t num_header_extents_at_front;
+       size_t extent_size; /* Data extent size; default is 4096 */
+       size_t key_size;
+       size_t extent_shift;
+       unsigned int extent_mask;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       struct crypto_tfm *tfm;
+       struct crypto_tfm *md5_tfm; /* Crypto context for generating
+                                    * the initialization vectors */
+       unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
+       unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
+       unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
+       unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
+       struct mutex cs_tfm_mutex;
+       struct mutex cs_md5_tfm_mutex;
+       struct mutex cs_mutex;
+};
+
+/* inode private data. */
+struct ecryptfs_inode_info {
+       struct inode vfs_inode;
+       struct inode *wii_inode;
+       struct ecryptfs_crypt_stat crypt_stat;
+};
+
+/* dentry private data. Each dentry must keep track of a lower
+ * vfsmount too. */
+struct ecryptfs_dentry_info {
+       struct dentry *wdi_dentry;
+       struct vfsmount *lower_mnt;
+       struct ecryptfs_crypt_stat *crypt_stat;
+};
+
+/**
+ * This struct is to enable a mount-wide passphrase/salt combo. This
+ * is more or less a stopgap to provide similar functionality to other
+ * crypto filesystems like EncFS or CFS until full policy support is
+ * implemented in eCryptfs.
+ */
+struct ecryptfs_mount_crypt_stat {
+       /* Pointers to memory we do not own, do not free these */
+#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001
+       u32 flags;
+       struct ecryptfs_auth_tok *global_auth_tok;
+       struct key *global_auth_tok_key;
+       size_t global_default_cipher_key_size;
+       struct crypto_tfm *global_key_tfm;
+       struct mutex global_key_tfm_mutex;
+       unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+                                                + 1];
+       unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+};
+
+/* superblock private data. */
+struct ecryptfs_sb_info {
+       struct super_block *wsi_sb;
+       struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+};
+
+/* file private data. */
+struct ecryptfs_file_info {
+       struct file *wfi_file;
+       struct ecryptfs_crypt_stat *crypt_stat;
+};
+
+/* auth_tok <=> encrypted_session_key mappings */
+struct ecryptfs_auth_tok_list_item {
+       unsigned char encrypted_session_key[ECRYPTFS_MAX_KEY_BYTES];
+       struct list_head list;
+       struct ecryptfs_auth_tok auth_tok;
+};
+
+static inline struct ecryptfs_file_info *
+ecryptfs_file_to_private(struct file *file)
+{
+       return (struct ecryptfs_file_info *)file->private_data;
+}
+
+static inline void
+ecryptfs_set_file_private(struct file *file,
+                         struct ecryptfs_file_info *file_info)
+{
+       file->private_data = file_info;
+}
+
+static inline struct file *ecryptfs_file_to_lower(struct file *file)
+{
+       return ((struct ecryptfs_file_info *)file->private_data)->wfi_file;
+}
+
+static inline void
+ecryptfs_set_file_lower(struct file *file, struct file *lower_file)
+{
+       ((struct ecryptfs_file_info *)file->private_data)->wfi_file =
+               lower_file;
+}
+
+static inline struct ecryptfs_inode_info *
+ecryptfs_inode_to_private(struct inode *inode)
+{
+       return container_of(inode, struct ecryptfs_inode_info, vfs_inode);
+}
+
+static inline struct inode *ecryptfs_inode_to_lower(struct inode *inode)
+{
+       return ecryptfs_inode_to_private(inode)->wii_inode;
+}
+
+static inline void
+ecryptfs_set_inode_lower(struct inode *inode, struct inode *lower_inode)
+{
+       ecryptfs_inode_to_private(inode)->wii_inode = lower_inode;
+}
+
+static inline struct ecryptfs_sb_info *
+ecryptfs_superblock_to_private(struct super_block *sb)
+{
+       return (struct ecryptfs_sb_info *)sb->s_fs_info;
+}
+
+static inline void
+ecryptfs_set_superblock_private(struct super_block *sb,
+                               struct ecryptfs_sb_info *sb_info)
+{
+       sb->s_fs_info = sb_info;
+}
+
+static inline struct super_block *
+ecryptfs_superblock_to_lower(struct super_block *sb)
+{
+       return ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb;
+}
+
+static inline void
+ecryptfs_set_superblock_lower(struct super_block *sb,
+                             struct super_block *lower_sb)
+{
+       ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb = lower_sb;
+}
+
+static inline struct ecryptfs_dentry_info *
+ecryptfs_dentry_to_private(struct dentry *dentry)
+{
+       return (struct ecryptfs_dentry_info *)dentry->d_fsdata;
+}
+
+static inline void
+ecryptfs_set_dentry_private(struct dentry *dentry,
+                           struct ecryptfs_dentry_info *dentry_info)
+{
+       dentry->d_fsdata = dentry_info;
+}
+
+static inline struct dentry *
+ecryptfs_dentry_to_lower(struct dentry *dentry)
+{
+       return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry;
+}
+
+static inline void
+ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry)
+{
+       ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry =
+               lower_dentry;
+}
+
+static inline struct vfsmount *
+ecryptfs_dentry_to_lower_mnt(struct dentry *dentry)
+{
+       return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt;
+}
+
+static inline void
+ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt)
+{
+       ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt =
+               lower_mnt;
+}
+
+#define ecryptfs_printk(type, fmt, arg...) \
+        __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg);
+void __ecryptfs_printk(const char *fmt, ...);
+
+extern const struct file_operations ecryptfs_main_fops;
+extern const struct file_operations ecryptfs_dir_fops;
+extern struct inode_operations ecryptfs_main_iops;
+extern struct inode_operations ecryptfs_dir_iops;
+extern struct inode_operations ecryptfs_symlink_iops;
+extern struct super_operations ecryptfs_sops;
+extern struct dentry_operations ecryptfs_dops;
+extern struct address_space_operations ecryptfs_aops;
+extern int ecryptfs_verbosity;
+
+extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
+extern struct kmem_cache *ecryptfs_file_info_cache;
+extern struct kmem_cache *ecryptfs_dentry_info_cache;
+extern struct kmem_cache *ecryptfs_inode_info_cache;
+extern struct kmem_cache *ecryptfs_sb_info_cache;
+extern struct kmem_cache *ecryptfs_header_cache_0;
+extern struct kmem_cache *ecryptfs_header_cache_1;
+extern struct kmem_cache *ecryptfs_header_cache_2;
+extern struct kmem_cache *ecryptfs_lower_page_cache;
+
+int ecryptfs_interpose(struct dentry *hidden_dentry,
+                      struct dentry *this_dentry, struct super_block *sb,
+                      int flag);
+int ecryptfs_fill_zeros(struct file *file, loff_t new_length);
+int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+                            const char *name, int length,
+                            char **decrypted_name);
+int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat,
+                            const char *name, int length,
+                            char **encoded_name);
+struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry);
+void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src);
+void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src);
+void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src);
+void ecryptfs_dump_hex(char *data, int bytes);
+int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
+                       int sg_size);
+int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_rotate_iv(unsigned char *iv);
+void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destruct_mount_crypt_stat(
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
+int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_write_inode_size_to_header(struct file *lower_file,
+                                       struct inode *lower_inode,
+                                       struct inode *inode);
+int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
+                           struct file *lower_file,
+                           unsigned long lower_page_index, int byte_offset,
+                           int region_bytes);
+int
+ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
+                          struct file *lower_file, int byte_offset,
+                          int region_size);
+int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
+                               struct file *lower_file);
+int ecryptfs_do_readpage(struct file *file, struct page *page,
+                        pgoff_t lower_page_index);
+int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
+                                    char **lower_virt,
+                                    struct inode *lower_inode,
+                                    unsigned long lower_page_index);
+int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
+                                             struct inode *lower_inode,
+                                             struct writeback_control *wbc);
+int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx);
+int ecryptfs_decrypt_page(struct file *file, struct page *page);
+int ecryptfs_write_headers(struct dentry *ecryptfs_dentry,
+                          struct file *lower_file);
+int ecryptfs_write_headers_virt(char *page_virt,
+                               struct ecryptfs_crypt_stat *crypt_stat,
+                               struct dentry *ecryptfs_dentry);
+int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
+                         struct file *lower_file);
+int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+int contains_ecryptfs_marker(char *data);
+int ecryptfs_read_header_region(char *data, struct dentry *dentry,
+                               struct vfsmount *mnt);
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code);
+void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_generate_key_packet_set(char *dest_base,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    struct dentry *ecryptfs_dentry,
+                                    size_t *len, size_t max);
+int process_request_key_err(long err_code);
+int
+ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
+                         unsigned char *src, struct dentry *ecryptfs_dentry);
+int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+                       char *cipher_name, size_t key_size);
+int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
+int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
+void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
+
+#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
new file mode 100644 (file)
index 0000000..c8550c9
--- /dev/null
@@ -0,0 +1,440 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
+ *             Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/security.h>
+#include <linux/smp_lock.h>
+#include <linux/compat.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_llseek
+ * @file: File we are seeking in
+ * @offset: The offset to seek to
+ * @origin: 2 - offset from i_size; 1 - offset from f_pos
+ *
+ * Returns the position we have seeked to, or negative on error
+ */
+static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin)
+{
+       loff_t rv;
+       loff_t new_end_pos;
+       int rc;
+       int expanding_file = 0;
+       struct inode *inode = file->f_mapping->host;
+
+       /* If our offset is past the end of our file, we're going to
+        * need to grow it so we have a valid length of 0's */
+       new_end_pos = offset;
+       switch (origin) {
+       case 2:
+               new_end_pos += i_size_read(inode);
+               expanding_file = 1;
+               break;
+       case 1:
+               new_end_pos += file->f_pos;
+               if (new_end_pos > i_size_read(inode)) {
+                       ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
+                                       "> i_size_read(inode)(=[0x%.16x])\n",
+                                       new_end_pos, i_size_read(inode));
+                       expanding_file = 1;
+               }
+               break;
+       default:
+               if (new_end_pos > i_size_read(inode)) {
+                       ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
+                                       "> i_size_read(inode)(=[0x%.16x])\n",
+                                       new_end_pos, i_size_read(inode));
+                       expanding_file = 1;
+               }
+       }
+       ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos);
+       if (expanding_file) {
+               rc = ecryptfs_truncate(file->f_dentry, new_end_pos);
+               if (rc) {
+                       rv = rc;
+                       ecryptfs_printk(KERN_ERR, "Error on attempt to "
+                                       "truncate to (higher) offset [0x%.16x];"
+                                       " rc = [%d]\n", new_end_pos, rc);
+                       goto out;
+               }
+       }
+       rv = generic_file_llseek(file, offset, origin);
+out:
+       return rv;
+}
+
+/**
+ * ecryptfs_read_update_atime
+ *
+ * generic_file_read updates the atime of upper layer inode.  But, it
+ * doesn't give us a chance to update the atime of the lower layer
+ * inode.  This function is a wrapper to generic_file_read.  It
+ * updates the atime of the lower level inode if generic_file_read
+ * returns without any errors. This is to be used only for file reads.
+ * The function to be used for directory reads is ecryptfs_read.
+ */
+static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
+                               const struct iovec *iov,
+                               unsigned long nr_segs, loff_t pos)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       struct vfsmount *lower_vfsmount;
+       struct file *file = iocb->ki_filp;
+
+       rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
+       /*
+        * Even though this is a async interface, we need to wait
+        * for IO to finish to update atime
+        */
+       if (-EIOCBQUEUED == rc)
+               rc = wait_on_sync_kiocb(iocb);
+       if (rc >= 0) {
+               lower_dentry = ecryptfs_dentry_to_lower(file->f_dentry);
+               lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_dentry);
+               touch_atime(lower_vfsmount, lower_dentry);
+       }
+       return rc;
+}
+
+struct ecryptfs_getdents_callback {
+       void *dirent;
+       struct dentry *dentry;
+       filldir_t filldir;
+       int err;
+       int filldir_called;
+       int entries_written;
+};
+
+/* Inspired by generic filldir in fs/readir.c */
+static int
+ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset,
+                u64 ino, unsigned int d_type)
+{
+       struct ecryptfs_crypt_stat *crypt_stat;
+       struct ecryptfs_getdents_callback *buf =
+           (struct ecryptfs_getdents_callback *)dirent;
+       int rc;
+       int decoded_length;
+       char *decoded_name;
+
+       crypt_stat = ecryptfs_dentry_to_private(buf->dentry)->crypt_stat;
+       buf->filldir_called++;
+       decoded_length = ecryptfs_decode_filename(crypt_stat, name, namelen,
+                                                 &decoded_name);
+       if (decoded_length < 0) {
+               rc = decoded_length;
+               goto out;
+       }
+       rc = buf->filldir(buf->dirent, decoded_name, decoded_length, offset,
+                         ino, d_type);
+       kfree(decoded_name);
+       if (rc >= 0)
+               buf->entries_written++;
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_readdir
+ * @file: The ecryptfs file struct
+ * @dirent: Directory entry
+ * @filldir: The filldir callback function
+ */
+static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+       int rc;
+       struct file *lower_file;
+       struct inode *inode;
+       struct ecryptfs_getdents_callback buf;
+
+       lower_file = ecryptfs_file_to_lower(file);
+       lower_file->f_pos = file->f_pos;
+       inode = file->f_dentry->d_inode;
+       memset(&buf, 0, sizeof(buf));
+       buf.dirent = dirent;
+       buf.dentry = file->f_dentry;
+       buf.filldir = filldir;
+retry:
+       buf.filldir_called = 0;
+       buf.entries_written = 0;
+       buf.err = 0;
+       rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
+       if (buf.err)
+               rc = buf.err;
+       if (buf.filldir_called && !buf.entries_written)
+               goto retry;
+       file->f_pos = lower_file->f_pos;
+       if (rc >= 0)
+               ecryptfs_copy_attr_atime(inode, lower_file->f_dentry->d_inode);
+       return rc;
+}
+
+struct kmem_cache *ecryptfs_file_info_cache;
+
+/**
+ * ecryptfs_open
+ * @inode: inode speciying file to open
+ * @file: Structure to return filled in
+ *
+ * Opens the file specified by inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_open(struct inode *inode, struct file *file)
+{
+       int rc = 0;
+       struct ecryptfs_crypt_stat *crypt_stat = NULL;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       struct dentry *ecryptfs_dentry = file->f_dentry;
+       /* Private value of ecryptfs_dentry allocated in
+        * ecryptfs_lookup() */
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+       struct inode *lower_inode = NULL;
+       struct file *lower_file = NULL;
+       struct vfsmount *lower_mnt;
+       struct ecryptfs_file_info *file_info;
+       int lower_flags;
+
+       /* Released in ecryptfs_release or end of function if failure */
+       file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL);
+       ecryptfs_set_file_private(file, file_info);
+       if (!file_info) {
+               ecryptfs_printk(KERN_ERR,
+                               "Error attempting to allocate memory\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       memset(file_info, 0, sizeof(*file_info));
+       lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+       crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+       mount_crypt_stat = &ecryptfs_superblock_to_private(
+               ecryptfs_dentry->d_sb)->mount_crypt_stat;
+       mutex_lock(&crypt_stat->cs_mutex);
+       if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) {
+               ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
+               /* Policy code enabled in future release */
+               ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED);
+               ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+       }
+       mutex_unlock(&crypt_stat->cs_mutex);
+       /* This mntget & dget is undone via fput when the file is released */
+       dget(lower_dentry);
+       lower_flags = file->f_flags;
+       if ((lower_flags & O_ACCMODE) == O_WRONLY)
+               lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
+       if (file->f_flags & O_APPEND)
+               lower_flags &= ~O_APPEND;
+       lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
+       mntget(lower_mnt);
+       /* Corresponding fput() in ecryptfs_release() */
+       lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
+       if (IS_ERR(lower_file)) {
+               rc = PTR_ERR(lower_file);
+               ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
+               goto out_puts;
+       }
+       ecryptfs_set_file_lower(file, lower_file);
+       /* Isn't this check the same as the one in lookup? */
+       lower_inode = lower_dentry->d_inode;
+       if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+               ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
+               ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+               rc = 0;
+               goto out;
+       }
+       mutex_lock(&crypt_stat->cs_mutex);
+       if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
+               if (!(mount_crypt_stat->flags
+                     & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+                       rc = -EIO;
+                       printk(KERN_WARNING "Attempt to read file that is "
+                              "not in a valid eCryptfs format, and plaintext "
+                              "passthrough mode is not enabled; returning "
+                              "-EIO\n");
+                       mutex_unlock(&crypt_stat->cs_mutex);
+                       goto out_puts;
+               }
+               crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
+               rc = 0;
+               mutex_unlock(&crypt_stat->cs_mutex);
+               goto out;
+       } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                       ECRYPTFS_POLICY_APPLIED)
+                  || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
+                                          ECRYPTFS_KEY_VALID)) {
+               rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file);
+               if (rc) {
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "Valid headers not found\n");
+                       if (!(mount_crypt_stat->flags
+                             & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+                               rc = -EIO;
+                               printk(KERN_WARNING "Attempt to read file that "
+                                      "is not in a valid eCryptfs format, "
+                                      "and plaintext passthrough mode is not "
+                                      "enabled; returning -EIO\n");
+                               mutex_unlock(&crypt_stat->cs_mutex);
+                               goto out_puts;
+                       }
+                       ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
+                                           ECRYPTFS_ENCRYPTED);
+                       rc = 0;
+                       mutex_unlock(&crypt_stat->cs_mutex);
+                       goto out;
+               }
+       }
+       mutex_unlock(&crypt_stat->cs_mutex);
+       ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] "
+                       "size: [0x%.16x]\n", inode, inode->i_ino,
+                       i_size_read(inode));
+       ecryptfs_set_file_lower(file, lower_file);
+       goto out;
+out_puts:
+       mntput(lower_mnt);
+       dput(lower_dentry);
+       kmem_cache_free(ecryptfs_file_info_cache,
+                       ecryptfs_file_to_private(file));
+out:
+       return rc;
+}
+
+static int ecryptfs_flush(struct file *file, fl_owner_t td)
+{
+       int rc = 0;
+       struct file *lower_file = NULL;
+
+       lower_file = ecryptfs_file_to_lower(file);
+       if (lower_file->f_op && lower_file->f_op->flush)
+               rc = lower_file->f_op->flush(lower_file, td);
+       return rc;
+}
+
+static int ecryptfs_release(struct inode *inode, struct file *file)
+{
+       struct file *lower_file = ecryptfs_file_to_lower(file);
+       struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
+       struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
+
+       fput(lower_file);
+       inode->i_blocks = lower_inode->i_blocks;
+       kmem_cache_free(ecryptfs_file_info_cache, file_info);
+       return 0;
+}
+
+static int
+ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+       struct file *lower_file = ecryptfs_file_to_lower(file);
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       struct inode *lower_inode = lower_dentry->d_inode;
+       int rc = -EINVAL;
+
+       if (lower_inode->i_fop->fsync) {
+               mutex_lock(&lower_inode->i_mutex);
+               rc = lower_inode->i_fop->fsync(lower_file, lower_dentry,
+                                              datasync);
+               mutex_unlock(&lower_inode->i_mutex);
+       }
+       return rc;
+}
+
+static int ecryptfs_fasync(int fd, struct file *file, int flag)
+{
+       int rc = 0;
+       struct file *lower_file = NULL;
+
+       lower_file = ecryptfs_file_to_lower(file);
+       if (lower_file->f_op && lower_file->f_op->fasync)
+               rc = lower_file->f_op->fasync(fd, lower_file, flag);
+       return rc;
+}
+
+static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos,
+                                size_t count, read_actor_t actor, void *target)
+{
+       struct file *lower_file = NULL;
+       int rc = -EINVAL;
+
+       lower_file = ecryptfs_file_to_lower(file);
+       if (lower_file->f_op && lower_file->f_op->sendfile)
+               rc = lower_file->f_op->sendfile(lower_file, ppos, count,
+                                               actor, target);
+
+       return rc;
+}
+
+static int ecryptfs_ioctl(struct inode *inode, struct file *file,
+                         unsigned int cmd, unsigned long arg);
+
+const struct file_operations ecryptfs_dir_fops = {
+       .readdir = ecryptfs_readdir,
+       .ioctl = ecryptfs_ioctl,
+       .mmap = generic_file_mmap,
+       .open = ecryptfs_open,
+       .flush = ecryptfs_flush,
+       .release = ecryptfs_release,
+       .fsync = ecryptfs_fsync,
+       .fasync = ecryptfs_fasync,
+       .sendfile = ecryptfs_sendfile,
+};
+
+const struct file_operations ecryptfs_main_fops = {
+       .llseek = ecryptfs_llseek,
+       .read = do_sync_read,
+       .aio_read = ecryptfs_read_update_atime,
+       .write = do_sync_write,
+       .aio_write = generic_file_aio_write,
+       .readdir = ecryptfs_readdir,
+       .ioctl = ecryptfs_ioctl,
+       .mmap = generic_file_mmap,
+       .open = ecryptfs_open,
+       .flush = ecryptfs_flush,
+       .release = ecryptfs_release,
+       .fsync = ecryptfs_fsync,
+       .fasync = ecryptfs_fasync,
+       .sendfile = ecryptfs_sendfile,
+};
+
+static int
+ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+              unsigned long arg)
+{
+       int rc = 0;
+       struct file *lower_file = NULL;
+
+       if (ecryptfs_file_to_private(file))
+               lower_file = ecryptfs_file_to_lower(file);
+       if (lower_file && lower_file->f_op && lower_file->f_op->ioctl)
+               rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode),
+                                            lower_file, cmd, arg);
+       else
+               rc = -ENOTTY;
+       return rc;
+}
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
new file mode 100644 (file)
index 0000000..efdd2b7
--- /dev/null
@@ -0,0 +1,1079 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2004 Erez Zadok
+ * Copyright (C) 2001-2004 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompsion <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/file.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/crypto.h>
+#include "ecryptfs_kernel.h"
+
+static struct dentry *lock_parent(struct dentry *dentry)
+{
+       struct dentry *dir;
+
+       dir = dget(dentry->d_parent);
+       mutex_lock(&(dir->d_inode->i_mutex));
+       return dir;
+}
+
+static void unlock_parent(struct dentry *dentry)
+{
+       mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
+       dput(dentry->d_parent);
+}
+
+static void unlock_dir(struct dentry *dir)
+{
+       mutex_unlock(&dir->d_inode->i_mutex);
+       dput(dir);
+}
+
+void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src)
+{
+       i_size_write(dst, i_size_read((struct inode *)src));
+       dst->i_blocks = src->i_blocks;
+}
+
+void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src)
+{
+       dest->i_atime = src->i_atime;
+}
+
+static void ecryptfs_copy_attr_times(struct inode *dest,
+                                    const struct inode *src)
+{
+       dest->i_atime = src->i_atime;
+       dest->i_mtime = src->i_mtime;
+       dest->i_ctime = src->i_ctime;
+}
+
+static void ecryptfs_copy_attr_timesizes(struct inode *dest,
+                                        const struct inode *src)
+{
+       dest->i_atime = src->i_atime;
+       dest->i_mtime = src->i_mtime;
+       dest->i_ctime = src->i_ctime;
+       ecryptfs_copy_inode_size(dest, src);
+}
+
+void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src)
+{
+       dest->i_mode = src->i_mode;
+       dest->i_nlink = src->i_nlink;
+       dest->i_uid = src->i_uid;
+       dest->i_gid = src->i_gid;
+       dest->i_rdev = src->i_rdev;
+       dest->i_atime = src->i_atime;
+       dest->i_mtime = src->i_mtime;
+       dest->i_ctime = src->i_ctime;
+       dest->i_blkbits = src->i_blkbits;
+       dest->i_flags = src->i_flags;
+}
+
+/**
+ * ecryptfs_create_underlying_file
+ * @lower_dir_inode: inode of the parent in the lower fs of the new file
+ * @lower_dentry: New file's dentry in the lower fs
+ * @ecryptfs_dentry: New file's dentry in ecryptfs
+ * @mode: The mode of the new file
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
+ *
+ * Creates the file in the lower file system.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
+                               struct dentry *dentry, int mode,
+                               struct nameidata *nd)
+{
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+       struct dentry *dentry_save;
+       struct vfsmount *vfsmount_save;
+       int rc;
+
+       dentry_save = nd->dentry;
+       vfsmount_save = nd->mnt;
+       nd->dentry = lower_dentry;
+       nd->mnt = lower_mnt;
+       rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
+       nd->dentry = dentry_save;
+       nd->mnt = vfsmount_save;
+       return rc;
+}
+
+/**
+ * ecryptfs_do_create
+ * @directory_inode: inode of the new file's dentry's parent in ecryptfs
+ * @ecryptfs_dentry: New file's dentry in ecryptfs
+ * @mode: The mode of the new file
+ * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
+ *
+ * Creates the underlying file and the eCryptfs inode which will link to
+ * it. It will also update the eCryptfs directory inode to mimic the
+ * stat of the lower directory inode.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_do_create(struct inode *directory_inode,
+                  struct dentry *ecryptfs_dentry, int mode,
+                  struct nameidata *nd)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       struct dentry *lower_dir_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+       lower_dir_dentry = lock_parent(lower_dentry);
+       if (unlikely(IS_ERR(lower_dir_dentry))) {
+               ecryptfs_printk(KERN_ERR, "Error locking directory of "
+                               "dentry\n");
+               rc = PTR_ERR(lower_dir_dentry);
+               goto out;
+       }
+       rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
+                                            ecryptfs_dentry, mode, nd);
+       if (unlikely(rc)) {
+               ecryptfs_printk(KERN_ERR,
+                               "Failure to create underlying file\n");
+               goto out_lock;
+       }
+       rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
+                               directory_inode->i_sb, 0);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n");
+               goto out_lock;
+       }
+       ecryptfs_copy_attr_timesizes(directory_inode,
+                                    lower_dir_dentry->d_inode);
+out_lock:
+       unlock_dir(lower_dir_dentry);
+out:
+       return rc;
+}
+
+/**
+ * grow_file
+ * @ecryptfs_dentry: the ecryptfs dentry
+ * @lower_file: The lower file
+ * @inode: The ecryptfs inode
+ * @lower_inode: The lower inode
+ *
+ * This is the code which will grow the file to its correct size.
+ */
+static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file,
+                    struct inode *inode, struct inode *lower_inode)
+{
+       int rc = 0;
+       struct file fake_file;
+       struct ecryptfs_file_info tmp_file_info;
+
+       memset(&fake_file, 0, sizeof(fake_file));
+       fake_file.f_dentry = ecryptfs_dentry;
+       memset(&tmp_file_info, 0, sizeof(tmp_file_info));
+       ecryptfs_set_file_private(&fake_file, &tmp_file_info);
+       ecryptfs_set_file_lower(&fake_file, lower_file);
+       rc = ecryptfs_fill_zeros(&fake_file, 1);
+       if (rc) {
+               ECRYPTFS_SET_FLAG(
+                       ecryptfs_inode_to_private(inode)->crypt_stat.flags,
+                       ECRYPTFS_SECURITY_WARNING);
+               ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros "
+                               "in file; rc = [%d]\n", rc);
+               goto out;
+       }
+       i_size_write(inode, 0);
+       ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode);
+       ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags,
+                         ECRYPTFS_NEW_FILE);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_initialize_file
+ *
+ * Cause the file to be changed from a basic empty file to an ecryptfs
+ * file with a header and first data page.
+ *
+ * Returns zero on success
+ */
+static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
+{
+       int rc = 0;
+       int lower_flags;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       struct dentry *lower_dentry;
+       struct dentry *tlower_dentry = NULL;
+       struct file *lower_file;
+       struct inode *inode, *lower_inode;
+       struct vfsmount *lower_mnt;
+
+       lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+       ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n",
+                       lower_dentry->d_name.name);
+       inode = ecryptfs_dentry->d_inode;
+       crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+       tlower_dentry = dget(lower_dentry);
+       if (!tlower_dentry) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
+               goto out;
+       }
+       lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
+#if BITS_PER_LONG != 32
+       lower_flags |= O_LARGEFILE;
+#endif
+       lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
+       mntget(lower_mnt);
+       /* Corresponding fput() at end of this function */
+       lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
+       if (IS_ERR(lower_file)) {
+               rc = PTR_ERR(lower_file);
+               ecryptfs_printk(KERN_ERR,
+                               "Error opening dentry; rc = [%i]\n", rc);
+               goto out;
+       }
+       /* fput(lower_file) should handle the puts if we do this */
+       lower_file->f_dentry = tlower_dentry;
+       lower_file->f_vfsmnt = lower_mnt;
+       lower_inode = tlower_dentry->d_inode;
+       if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+               ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
+               ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
+               goto out_fput;
+       }
+       ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+       ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
+       rc = ecryptfs_new_file_context(ecryptfs_dentry);
+       if (rc) {
+               ecryptfs_printk(KERN_DEBUG, "Error creating new file "
+                               "context\n");
+               goto out_fput;
+       }
+       rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file);
+       if (rc) {
+               ecryptfs_printk(KERN_DEBUG, "Error writing headers\n");
+               goto out_fput;
+       }
+       rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
+out_fput:
+       fput(lower_file);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_create
+ * @dir: The inode of the directory in which to create the file.
+ * @dentry: The eCryptfs dentry
+ * @mode: The mode of the new file.
+ * @nd: nameidata
+ *
+ * Creates a new file.
+ *
+ * Returns zero on success; non-zero on error condition
+ */
+static int
+ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
+               int mode, struct nameidata *nd)
+{
+       int rc;
+
+       rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd);
+       if (unlikely(rc)) {
+               ecryptfs_printk(KERN_WARNING, "Failed to create file in"
+                               "lower filesystem\n");
+               goto out;
+       }
+       /* At this point, a file exists on "disk"; we need to make sure
+        * that this on disk file is prepared to be an ecryptfs file */
+       rc = ecryptfs_initialize_file(ecryptfs_dentry);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_lookup
+ * @dir: inode
+ * @dentry: The dentry
+ * @nd: nameidata, may be NULL
+ *
+ * Find a file on disk. If the file does not exist, then we'll add it to the
+ * dentry cache and continue on to read it from the disk.
+ */
+static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
+                                     struct nameidata *nd)
+{
+       int rc = 0;
+       struct dentry *lower_dir_dentry;
+       struct dentry *lower_dentry;
+       struct vfsmount *lower_mnt;
+       struct dentry *tlower_dentry = NULL;
+       char *encoded_name;
+       unsigned int encoded_namelen;
+       struct ecryptfs_crypt_stat *crypt_stat = NULL;
+       char *page_virt = NULL;
+       struct inode *lower_inode;
+       u64 file_size;
+
+       lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
+       dentry->d_op = &ecryptfs_dops;
+       if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
+           || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, "..")))
+               goto out_drop;
+       encoded_namelen = ecryptfs_encode_filename(crypt_stat,
+                                                  dentry->d_name.name,
+                                                  dentry->d_name.len,
+                                                  &encoded_name);
+       if (encoded_namelen < 0) {
+               rc = encoded_namelen;
+               goto out_drop;
+       }
+       ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
+                       "= [%d]\n", encoded_name, encoded_namelen);
+       lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
+                                     encoded_namelen - 1);
+       kfree(encoded_name);
+       lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
+       if (IS_ERR(lower_dentry)) {
+               ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
+               rc = PTR_ERR(lower_dentry);
+               goto out_drop;
+       }
+       ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->"
+                       "d_name.name = [%s]\n", lower_dentry,
+               lower_dentry->d_name.name);
+       lower_inode = lower_dentry->d_inode;
+       ecryptfs_copy_attr_atime(dir, lower_dir_dentry->d_inode);
+       BUG_ON(!atomic_read(&lower_dentry->d_count));
+       ecryptfs_set_dentry_private(dentry,
+                                   kmem_cache_alloc(ecryptfs_dentry_info_cache,
+                                                    SLAB_KERNEL));
+       if (!ecryptfs_dentry_to_private(dentry)) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting "
+                               "to allocate ecryptfs_dentry_info struct\n");
+               goto out_dput;
+       }
+       ecryptfs_set_dentry_lower(dentry, lower_dentry);
+       ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);
+       if (!lower_dentry->d_inode) {
+               /* We want to add because we couldn't find in lower */
+               d_add(dentry, NULL);
+               goto out;
+       }
+       rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error interposing\n");
+               goto out_dput;
+       }
+       if (S_ISDIR(lower_inode->i_mode)) {
+               ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n");
+               goto out;
+       }
+       if (S_ISLNK(lower_inode->i_mode)) {
+               ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n");
+               goto out;
+       }
+       if (!nd) {
+               ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave"
+                               "as we *think* we are about to unlink\n");
+               goto out;
+       }
+       tlower_dentry = dget(lower_dentry);
+       if (!tlower_dentry || IS_ERR(tlower_dentry)) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n");
+               goto out_dput;
+       }
+       /* Released in this function */
+       page_virt =
+           (char *)kmem_cache_alloc(ecryptfs_header_cache_2,
+                                    SLAB_USER);
+       if (!page_virt) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR,
+                               "Cannot ecryptfs_kmalloc a page\n");
+               goto out_dput;
+       }
+       memset(page_virt, 0, PAGE_CACHE_SIZE);
+       rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
+       crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+       if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
+               ecryptfs_set_default_sizes(crypt_stat);
+       if (rc) {
+               rc = 0;
+               ecryptfs_printk(KERN_WARNING, "Error reading header region;"
+                               " assuming unencrypted\n");
+       } else {
+               if (!contains_ecryptfs_marker(page_virt
+                                             + ECRYPTFS_FILE_SIZE_BYTES)) {
+                       kmem_cache_free(ecryptfs_header_cache_2, page_virt);
+                       goto out;
+               }
+               memcpy(&file_size, page_virt, sizeof(file_size));
+               file_size = be64_to_cpu(file_size);
+               i_size_write(dentry->d_inode, (loff_t)file_size);
+       }
+       kmem_cache_free(ecryptfs_header_cache_2, page_virt);
+       goto out;
+
+out_dput:
+       dput(lower_dentry);
+       if (tlower_dentry)
+               dput(tlower_dentry);
+out_drop:
+       d_drop(dentry);
+out:
+       return ERR_PTR(rc);
+}
+
+static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
+                        struct dentry *new_dentry)
+{
+       struct dentry *lower_old_dentry;
+       struct dentry *lower_new_dentry;
+       struct dentry *lower_dir_dentry;
+       u64 file_size_save;
+       int rc;
+
+       file_size_save = i_size_read(old_dentry->d_inode);
+       lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+       lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+       dget(lower_old_dentry);
+       dget(lower_new_dentry);
+       lower_dir_dentry = lock_parent(lower_new_dentry);
+       rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
+                     lower_new_dentry);
+       if (rc || !lower_new_dentry->d_inode)
+               goto out_lock;
+       rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
+       if (rc)
+               goto out_lock;
+       ecryptfs_copy_attr_timesizes(dir, lower_new_dentry->d_inode);
+       old_dentry->d_inode->i_nlink =
+               ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
+       i_size_write(new_dentry->d_inode, file_size_save);
+out_lock:
+       unlock_dir(lower_dir_dentry);
+       dput(lower_new_dentry);
+       dput(lower_old_dentry);
+       if (!new_dentry->d_inode)
+               d_drop(new_dentry);
+       return rc;
+}
+
+static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+       int rc = 0;
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+
+       lock_parent(lower_dentry);
+       rc = vfs_unlink(lower_dir_inode, lower_dentry);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n");
+               goto out_unlock;
+       }
+       ecryptfs_copy_attr_times(dir, lower_dir_inode);
+       dentry->d_inode->i_nlink =
+               ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink;
+       dentry->d_inode->i_ctime = dir->i_ctime;
+out_unlock:
+       unlock_parent(lower_dentry);
+       return rc;
+}
+
+static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
+                           const char *symname)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       struct dentry *lower_dir_dentry;
+       umode_t mode;
+       char *encoded_symname;
+       unsigned int encoded_symlen;
+       struct ecryptfs_crypt_stat *crypt_stat = NULL;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       dget(lower_dentry);
+       lower_dir_dentry = lock_parent(lower_dentry);
+       mode = S_IALLUGO;
+       encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
+                                                 strlen(symname),
+                                                 &encoded_symname);
+       if (encoded_symlen < 0) {
+               rc = encoded_symlen;
+               goto out_lock;
+       }
+       rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
+                        encoded_symname, mode);
+       kfree(encoded_symname);
+       if (rc || !lower_dentry->d_inode)
+               goto out_lock;
+       rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+       if (rc)
+               goto out_lock;
+       ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+out_lock:
+       unlock_dir(lower_dir_dentry);
+       dput(lower_dentry);
+       if (!dentry->d_inode)
+               d_drop(dentry);
+       return rc;
+}
+
+static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       struct dentry *lower_dir_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       lower_dir_dentry = lock_parent(lower_dentry);
+       rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
+       if (rc || !lower_dentry->d_inode)
+               goto out;
+       rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+       if (rc)
+               goto out;
+       ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+       dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+out:
+       unlock_dir(lower_dir_dentry);
+       if (!dentry->d_inode)
+               d_drop(dentry);
+       return rc;
+}
+
+static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+       int rc = 0;
+       struct dentry *tdentry = NULL;
+       struct dentry *lower_dentry;
+       struct dentry *tlower_dentry = NULL;
+       struct dentry *lower_dir_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!(tdentry = dget(dentry))) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n",
+                               dentry);
+               goto out;
+       }
+       lower_dir_dentry = lock_parent(lower_dentry);
+       if (!(tlower_dentry = dget(lower_dentry))) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry "
+                               "[%p]\n", lower_dentry);
+               goto out;
+       }
+       rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+       if (!rc) {
+               d_delete(tlower_dentry);
+               tlower_dentry = NULL;
+       }
+       ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode);
+       dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
+       unlock_dir(lower_dir_dentry);
+       if (!rc)
+               d_drop(dentry);
+out:
+       if (tdentry)
+               dput(tdentry);
+       if (tlower_dentry)
+               dput(tlower_dentry);
+       return rc;
+}
+
+static int
+ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       struct dentry *lower_dir_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       lower_dir_dentry = lock_parent(lower_dentry);
+       rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
+       if (rc || !lower_dentry->d_inode)
+               goto out;
+       rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+       if (rc)
+               goto out;
+       ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode);
+out:
+       unlock_dir(lower_dir_dentry);
+       if (!dentry->d_inode)
+               d_drop(dentry);
+       return rc;
+}
+
+static int
+ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+               struct inode *new_dir, struct dentry *new_dentry)
+{
+       int rc;
+       struct dentry *lower_old_dentry;
+       struct dentry *lower_new_dentry;
+       struct dentry *lower_old_dir_dentry;
+       struct dentry *lower_new_dir_dentry;
+
+       lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+       lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+       dget(lower_old_dentry);
+       dget(lower_new_dentry);
+       lower_old_dir_dentry = dget_parent(lower_old_dentry);
+       lower_new_dir_dentry = dget_parent(lower_new_dentry);
+       lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+       rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
+                       lower_new_dir_dentry->d_inode, lower_new_dentry);
+       if (rc)
+               goto out_lock;
+       ecryptfs_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
+       if (new_dir != old_dir)
+               ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
+out_lock:
+       unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+       dput(lower_new_dentry);
+       dput(lower_old_dentry);
+       return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz)
+{
+       int rc;
+       struct dentry *lower_dentry;
+       char *decoded_name;
+       char *lower_buf;
+       mm_segment_t old_fs;
+       struct ecryptfs_crypt_stat *crypt_stat;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op ||
+           !lower_dentry->d_inode->i_op->readlink) {
+               rc = -EINVAL;
+               goto out;
+       }
+       /* Released in this function */
+       lower_buf = kmalloc(bufsiz, GFP_KERNEL);
+       if (lower_buf == NULL) {
+               ecryptfs_printk(KERN_ERR, "Out of memory\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       old_fs = get_fs();
+       set_fs(get_ds());
+       ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ "
+                       "lower_dentry->d_name.name = [%s]\n",
+                       lower_dentry->d_name.name);
+       rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
+                                                  (char __user *)lower_buf,
+                                                  bufsiz);
+       set_fs(old_fs);
+       if (rc >= 0) {
+               crypt_stat = NULL;
+               rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc,
+                                             &decoded_name);
+               if (rc == -ENOMEM)
+                       goto out_free_lower_buf;
+               if (rc > 0) {
+                       ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes "
+                                       "to userspace: [%*s]\n", rc,
+                                       decoded_name);
+                       if (copy_to_user(buf, decoded_name, rc))
+                               rc = -EFAULT;
+               }
+               kfree(decoded_name);
+               ecryptfs_copy_attr_atime(dentry->d_inode,
+                                        lower_dentry->d_inode);
+       }
+out_free_lower_buf:
+       kfree(lower_buf);
+out:
+       return rc;
+}
+
+static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       char *buf;
+       int len = PAGE_SIZE, rc;
+       mm_segment_t old_fs;
+
+       /* Released in ecryptfs_put_link(); only release here on error */
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       old_fs = get_fs();
+       set_fs(get_ds());
+       ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ "
+                       "dentry->d_name.name = [%s]\n", dentry->d_name.name);
+       rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
+       buf[rc] = '\0';
+       set_fs(old_fs);
+       if (rc < 0)
+               goto out_free;
+       rc = 0;
+       nd_set_link(nd, buf);
+       goto out;
+out_free:
+       kfree(buf);
+out:
+       return ERR_PTR(rc);
+}
+
+static void
+ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
+{
+       /* Free the char* */
+       kfree(nd_get_link(nd));
+}
+
+/**
+ * upper_size_to_lower_size
+ * @crypt_stat: Crypt_stat associated with file
+ * @upper_size: Size of the upper file
+ *
+ * Calculate the requried size of the lower file based on the
+ * specified size of the upper file. This calculation is based on the
+ * number of headers in the underlying file and the extent size.
+ *
+ * Returns Calculated size of the lower file.
+ */
+static loff_t
+upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
+                        loff_t upper_size)
+{
+       loff_t lower_size;
+
+       lower_size = ( crypt_stat->header_extent_size
+                      * crypt_stat->num_header_extents_at_front );
+       if (upper_size != 0) {
+               loff_t num_extents;
+
+               num_extents = upper_size >> crypt_stat->extent_shift;
+               if (upper_size & ~crypt_stat->extent_mask)
+                       num_extents++;
+               lower_size += (num_extents * crypt_stat->extent_size);
+       }
+       return lower_size;
+}
+
+/**
+ * ecryptfs_truncate
+ * @dentry: The ecryptfs layer dentry
+ * @new_length: The length to expand the file to
+ *
+ * Function to handle truncations modifying the size of the file. Note
+ * that the file sizes are interpolated. When expanding, we are simply
+ * writing strings of 0's out. When truncating, we need to modify the
+ * underlying file size according to the page index interpolations.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+{
+       int rc = 0;
+       struct inode *inode = dentry->d_inode;
+       struct dentry *lower_dentry;
+       struct vfsmount *lower_mnt;
+       struct file fake_ecryptfs_file, *lower_file = NULL;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       loff_t i_size = i_size_read(inode);
+       loff_t lower_size_before_truncate;
+       loff_t lower_size_after_truncate;
+
+       if (unlikely((new_length == i_size)))
+               goto out;
+       crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+       /* Set up a fake ecryptfs file, this is used to interface with
+        * the file in the underlying filesystem so that the
+        * truncation has an effect there as well. */
+       memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file));
+       fake_ecryptfs_file.f_dentry = dentry;
+       /* Released at out_free: label */
+       ecryptfs_set_file_private(&fake_ecryptfs_file,
+                                 kmem_cache_alloc(ecryptfs_file_info_cache,
+                                                  SLAB_KERNEL));
+       if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       /* This dget & mntget is released through fput at out_fput: */
+       dget(lower_dentry);
+       lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+       mntget(lower_mnt);
+       lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
+       if (unlikely(IS_ERR(lower_file))) {
+               rc = PTR_ERR(lower_file);
+               goto out_free;
+       }
+       ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
+       /* Switch on growing or shrinking file */
+       if (new_length > i_size) {
+               rc = ecryptfs_fill_zeros(&fake_ecryptfs_file, new_length);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR,
+                                       "Problem with fill_zeros\n");
+                       goto out_fput;
+               }
+               i_size_write(inode, new_length);
+               rc = ecryptfs_write_inode_size_to_header(lower_file,
+                                                        lower_dentry->d_inode,
+                                                        inode);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR,
+                                       "Problem with ecryptfs_write"
+                                       "_inode_size\n");
+                       goto out_fput;
+               }
+       } else { /* new_length < i_size_read(inode) */
+               vmtruncate(inode, new_length);
+               ecryptfs_write_inode_size_to_header(lower_file,
+                                                   lower_dentry->d_inode,
+                                                   inode);
+               /* We are reducing the size of the ecryptfs file, and need to
+                * know if we need to reduce the size of the lower file. */
+               lower_size_before_truncate =
+                   upper_size_to_lower_size(crypt_stat, i_size);
+               lower_size_after_truncate =
+                   upper_size_to_lower_size(crypt_stat, new_length);
+               if (lower_size_after_truncate < lower_size_before_truncate)
+                       vmtruncate(lower_dentry->d_inode,
+                                  lower_size_after_truncate);
+       }
+       /* Update the access times */
+       lower_dentry->d_inode->i_mtime = lower_dentry->d_inode->i_ctime
+               = CURRENT_TIME;
+       mark_inode_dirty_sync(inode);
+out_fput:
+       fput(lower_file);
+out_free:
+       if (ecryptfs_file_to_private(&fake_ecryptfs_file))
+               kmem_cache_free(ecryptfs_file_info_cache,
+                               ecryptfs_file_to_private(&fake_ecryptfs_file));
+out:
+       return rc;
+}
+
+static int
+ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+       int rc;
+
+        if (nd) {
+               struct vfsmount *vfsmnt_save = nd->mnt;
+               struct dentry *dentry_save = nd->dentry;
+
+               nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
+               nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
+               rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
+               nd->mnt = vfsmnt_save;
+               nd->dentry = dentry_save;
+        } else
+               rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
+        return rc;
+}
+
+/**
+ * ecryptfs_setattr
+ * @dentry: dentry handle to the inode to modify
+ * @ia: Structure with flags of what to change and values
+ *
+ * Updates the metadata of an inode. If the update is to the size
+ * i.e. truncation, then ecryptfs_truncate will handle the size modification
+ * of both the ecryptfs inode and the lower inode.
+ *
+ * All other metadata changes will be passed right to the lower filesystem,
+ * and we will just update our inode to look like the lower.
+ */
+static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+{
+       int rc = 0;
+       struct dentry *lower_dentry;
+       struct inode *inode;
+       struct inode *lower_inode;
+       struct ecryptfs_crypt_stat *crypt_stat;
+
+       crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       inode = dentry->d_inode;
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       if (ia->ia_valid & ATTR_SIZE) {
+               ecryptfs_printk(KERN_DEBUG,
+                               "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n",
+                               ia->ia_valid, ATTR_SIZE);
+               rc = ecryptfs_truncate(dentry, ia->ia_size);
+               /* ecryptfs_truncate handles resizing of the lower file */
+               ia->ia_valid &= ~ATTR_SIZE;
+               ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n",
+                               ia->ia_valid);
+               if (rc < 0)
+                       goto out;
+       }
+       rc = notify_change(lower_dentry, ia);
+out:
+       ecryptfs_copy_attr_all(inode, lower_inode);
+       return rc;
+}
+
+static int
+ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+                 size_t size, int flags)
+{
+       int rc = 0;
+       struct dentry *lower_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->setxattr) {
+               rc = -ENOSYS;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+       rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value,
+                                                  size, flags);
+       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+       return rc;
+}
+
+static ssize_t
+ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
+                 size_t size)
+{
+       int rc = 0;
+       struct dentry *lower_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->getxattr) {
+               rc = -ENOSYS;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+       rc = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value,
+                                                  size);
+       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+       return rc;
+}
+
+static ssize_t
+ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
+{
+       int rc = 0;
+       struct dentry *lower_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->listxattr) {
+               rc = -ENOSYS;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+       rc = lower_dentry->d_inode->i_op->listxattr(lower_dentry, list, size);
+       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+       return rc;
+}
+
+static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
+{
+       int rc = 0;
+       struct dentry *lower_dentry;
+
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->removexattr) {
+               rc = -ENOSYS;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+       rc = lower_dentry->d_inode->i_op->removexattr(lower_dentry, name);
+       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+out:
+       return rc;
+}
+
+int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode)
+{
+       if ((ecryptfs_inode_to_lower(inode)
+            == (struct inode *)candidate_lower_inode))
+               return 1;
+       else
+               return 0;
+}
+
+int ecryptfs_inode_set(struct inode *inode, void *lower_inode)
+{
+       ecryptfs_init_inode(inode, (struct inode *)lower_inode);
+       return 0;
+}
+
+struct inode_operations ecryptfs_symlink_iops = {
+       .readlink = ecryptfs_readlink,
+       .follow_link = ecryptfs_follow_link,
+       .put_link = ecryptfs_put_link,
+       .permission = ecryptfs_permission,
+       .setattr = ecryptfs_setattr,
+       .setxattr = ecryptfs_setxattr,
+       .getxattr = ecryptfs_getxattr,
+       .listxattr = ecryptfs_listxattr,
+       .removexattr = ecryptfs_removexattr
+};
+
+struct inode_operations ecryptfs_dir_iops = {
+       .create = ecryptfs_create,
+       .lookup = ecryptfs_lookup,
+       .link = ecryptfs_link,
+       .unlink = ecryptfs_unlink,
+       .symlink = ecryptfs_symlink,
+       .mkdir = ecryptfs_mkdir,
+       .rmdir = ecryptfs_rmdir,
+       .mknod = ecryptfs_mknod,
+       .rename = ecryptfs_rename,
+       .permission = ecryptfs_permission,
+       .setattr = ecryptfs_setattr,
+       .setxattr = ecryptfs_setxattr,
+       .getxattr = ecryptfs_getxattr,
+       .listxattr = ecryptfs_listxattr,
+       .removexattr = ecryptfs_removexattr
+};
+
+struct inode_operations ecryptfs_main_iops = {
+       .permission = ecryptfs_permission,
+       .setattr = ecryptfs_setattr,
+       .setxattr = ecryptfs_setxattr,
+       .getxattr = ecryptfs_getxattr,
+       .listxattr = ecryptfs_listxattr,
+       .removexattr = ecryptfs_removexattr
+};
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
new file mode 100644 (file)
index 0000000..ba45478
--- /dev/null
@@ -0,0 +1,1061 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * In-kernel key management code.  Includes functions to parse and
+ * write authentication token-related packets with the underlying
+ * file.
+ *
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/pagemap.h>
+#include <linux/key.h>
+#include <linux/random.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * request_key returned an error instead of a valid key address;
+ * determine the type of error, make appropriate log entries, and
+ * return an error code.
+ */
+int process_request_key_err(long err_code)
+{
+       int rc = 0;
+
+       switch (err_code) {
+       case ENOKEY:
+               ecryptfs_printk(KERN_WARNING, "No key\n");
+               rc = -ENOENT;
+               break;
+       case EKEYEXPIRED:
+               ecryptfs_printk(KERN_WARNING, "Key expired\n");
+               rc = -ETIME;
+               break;
+       case EKEYREVOKED:
+               ecryptfs_printk(KERN_WARNING, "Key revoked\n");
+               rc = -EINVAL;
+               break;
+       default:
+               ecryptfs_printk(KERN_WARNING, "Unknown error code: "
+                               "[0x%.16x]\n", err_code);
+               rc = -EINVAL;
+       }
+       return rc;
+}
+
+static void wipe_auth_tok_list(struct list_head *auth_tok_list_head)
+{
+       struct list_head *walker;
+       struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+
+       walker = auth_tok_list_head->next;
+       while (walker != auth_tok_list_head) {
+               auth_tok_list_item =
+                   list_entry(walker, struct ecryptfs_auth_tok_list_item,
+                              list);
+               walker = auth_tok_list_item->list.next;
+               memset(auth_tok_list_item, 0,
+                      sizeof(struct ecryptfs_auth_tok_list_item));
+               kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
+                               auth_tok_list_item);
+       }
+}
+
+struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
+
+/**
+ * parse_packet_length
+ * @data: Pointer to memory containing length at offset
+ * @size: This function writes the decoded size to this memory
+ *        address; zero on error
+ * @length_size: The number of bytes occupied by the encoded length
+ *
+ * Returns Zero on success
+ */
+static int parse_packet_length(unsigned char *data, size_t *size,
+                              size_t *length_size)
+{
+       int rc = 0;
+
+       (*length_size) = 0;
+       (*size) = 0;
+       if (data[0] < 192) {
+               /* One-byte length */
+               (*size) = data[0];
+               (*length_size) = 1;
+       } else if (data[0] < 224) {
+               /* Two-byte length */
+               (*size) = ((data[0] - 192) * 256);
+               (*size) += (data[1] + 192);
+               (*length_size) = 2;
+       } else if (data[0] == 255) {
+               /* Five-byte length; we're not supposed to see this */
+               ecryptfs_printk(KERN_ERR, "Five-byte packet length not "
+                               "supported\n");
+               rc = -EINVAL;
+               goto out;
+       } else {
+               ecryptfs_printk(KERN_ERR, "Error parsing packet length\n");
+               rc = -EINVAL;
+               goto out;
+       }
+out:
+       return rc;
+}
+
+/**
+ * write_packet_length
+ * @dest: The byte array target into which to write the
+ *       length. Must have at least 5 bytes allocated.
+ * @size: The length to write.
+ * @packet_size_length: The number of bytes used to encode the
+ *                      packet length is written to this address.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int write_packet_length(char *dest, size_t size,
+                              size_t *packet_size_length)
+{
+       int rc = 0;
+
+       if (size < 192) {
+               dest[0] = size;
+               (*packet_size_length) = 1;
+       } else if (size < 65536) {
+               dest[0] = (((size - 192) / 256) + 192);
+               dest[1] = ((size - 192) % 256);
+               (*packet_size_length) = 2;
+       } else {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_WARNING,
+                               "Unsupported packet size: [%d]\n", size);
+       }
+       return rc;
+}
+
+/**
+ * parse_tag_3_packet
+ * @crypt_stat: The cryptographic context to modify based on packet
+ *              contents.
+ * @data: The raw bytes of the packet.
+ * @auth_tok_list: eCryptfs parses packets into authentication tokens;
+ *                 a new authentication token will be placed at the end
+ *                 of this list for this packet.
+ * @new_auth_tok: Pointer to a pointer to memory that this function
+ *                allocates; sets the memory address of the pointer to
+ *                NULL on error. This object is added to the
+ *                auth_tok_list.
+ * @packet_size: This function writes the size of the parsed packet
+ *               into this memory location; zero on error.
+ * @max_packet_size: maximum number of bytes to parse
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
+                  unsigned char *data, struct list_head *auth_tok_list,
+                  struct ecryptfs_auth_tok **new_auth_tok,
+                  size_t *packet_size, size_t max_packet_size)
+{
+       int rc = 0;
+       size_t body_size;
+       struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+       size_t length_size;
+
+       (*packet_size) = 0;
+       (*new_auth_tok) = NULL;
+
+       /* we check that:
+        *   one byte for the Tag 3 ID flag
+        *   two bytes for the body size
+        * do not exceed the maximum_packet_size
+        */
+       if (unlikely((*packet_size) + 3 > max_packet_size)) {
+               ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* check for Tag 3 identifyer - one byte */
+       if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) {
+               ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n",
+                               ECRYPTFS_TAG_3_PACKET_TYPE);
+               rc = -EINVAL;
+               goto out;
+       }
+       /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or
+        * at end of function upon failure */
+       auth_tok_list_item =
+           kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL);
+       if (!auth_tok_list_item) {
+               ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       memset(auth_tok_list_item, 0,
+              sizeof(struct ecryptfs_auth_tok_list_item));
+       (*new_auth_tok) = &auth_tok_list_item->auth_tok;
+
+       /* check for body size - one to two bytes */
+       rc = parse_packet_length(&data[(*packet_size)], &body_size,
+                                &length_size);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
+                               "rc = [%d]\n", rc);
+               goto out_free;
+       }
+       if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) {
+               ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
+                               body_size);
+               rc = -EINVAL;
+               goto out_free;
+       }
+       (*packet_size) += length_size;
+
+       /* now we know the length of the remainting Tag 3 packet size:
+        *   5 fix bytes for: version string, cipher, S2K ID, hash algo,
+        *                    number of hash iterations
+        *   ECRYPTFS_SALT_SIZE bytes for salt
+        *   body_size bytes minus the stuff above is the encrypted key size
+        */
+       if (unlikely((*packet_size) + body_size > max_packet_size)) {
+               ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+               rc = -EINVAL;
+               goto out_free;
+       }
+
+       /* There are 5 characters of additional information in the
+        * packet */
+       (*new_auth_tok)->session_key.encrypted_key_size =
+               body_size - (0x05 + ECRYPTFS_SALT_SIZE);
+       ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
+                       (*new_auth_tok)->session_key.encrypted_key_size);
+
+       /* Version 4 (from RFC2440) - one byte */
+       if (unlikely(data[(*packet_size)++] != 0x04)) {
+               ecryptfs_printk(KERN_DEBUG, "Unknown version number "
+                               "[%d]\n", data[(*packet_size) - 1]);
+               rc = -EINVAL;
+               goto out_free;
+       }
+
+       /* cipher - one byte */
+       ecryptfs_cipher_code_to_string(crypt_stat->cipher,
+                                      (u16)data[(*packet_size)]);
+       /* A little extra work to differentiate among the AES key
+        * sizes; see RFC2440 */
+       switch(data[(*packet_size)++]) {
+       case RFC2440_CIPHER_AES_192:
+               crypt_stat->key_size = 24;
+               break;
+       default:
+               crypt_stat->key_size =
+                       (*new_auth_tok)->session_key.encrypted_key_size;
+       }
+       ecryptfs_init_crypt_ctx(crypt_stat);
+       /* S2K identifier 3 (from RFC2440) */
+       if (unlikely(data[(*packet_size)++] != 0x03)) {
+               ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently "
+                               "supported\n");
+               rc = -ENOSYS;
+               goto out_free;
+       }
+
+       /* TODO: finish the hash mapping */
+       /* hash algorithm - one byte */
+       switch (data[(*packet_size)++]) {
+       case 0x01: /* See RFC2440 for these numbers and their mappings */
+               /* Choose MD5 */
+               /* salt - ECRYPTFS_SALT_SIZE bytes */
+               memcpy((*new_auth_tok)->token.password.salt,
+                      &data[(*packet_size)], ECRYPTFS_SALT_SIZE);
+               (*packet_size) += ECRYPTFS_SALT_SIZE;
+
+               /* This conversion was taken straight from RFC2440 */
+               /* number of hash iterations - one byte */
+               (*new_auth_tok)->token.password.hash_iterations =
+                       ((u32) 16 + (data[(*packet_size)] & 15))
+                               << ((data[(*packet_size)] >> 4) + 6);
+               (*packet_size)++;
+
+               /* encrypted session key -
+                *   (body_size-5-ECRYPTFS_SALT_SIZE) bytes */
+               memcpy((*new_auth_tok)->session_key.encrypted_key,
+                      &data[(*packet_size)],
+                      (*new_auth_tok)->session_key.encrypted_key_size);
+               (*packet_size) +=
+                       (*new_auth_tok)->session_key.encrypted_key_size;
+               (*new_auth_tok)->session_key.flags &=
+                       ~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
+               (*new_auth_tok)->session_key.flags |=
+                       ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
+               (*new_auth_tok)->token.password.hash_algo = 0x01;
+               break;
+       default:
+               ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: "
+                               "[%d]\n", data[(*packet_size) - 1]);
+               rc = -ENOSYS;
+               goto out_free;
+       }
+       (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD;
+       /* TODO: Parametarize; we might actually want userspace to
+        * decrypt the session key. */
+       ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
+                           ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
+       ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags,
+                           ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT);
+       list_add(&auth_tok_list_item->list, auth_tok_list);
+       goto out;
+out_free:
+       (*new_auth_tok) = NULL;
+       memset(auth_tok_list_item, 0,
+              sizeof(struct ecryptfs_auth_tok_list_item));
+       kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
+                       auth_tok_list_item);
+out:
+       if (rc)
+               (*packet_size) = 0;
+       return rc;
+}
+
+/**
+ * parse_tag_11_packet
+ * @data: The raw bytes of the packet
+ * @contents: This function writes the data contents of the literal
+ *            packet into this memory location
+ * @max_contents_bytes: The maximum number of bytes that this function
+ *                      is allowed to write into contents
+ * @tag_11_contents_size: This function writes the size of the parsed
+ *                        contents into this memory location; zero on
+ *                        error
+ * @packet_size: This function writes the size of the parsed packet
+ *               into this memory location; zero on error
+ * @max_packet_size: maximum number of bytes to parse
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+parse_tag_11_packet(unsigned char *data, unsigned char *contents,
+                   size_t max_contents_bytes, size_t *tag_11_contents_size,
+                   size_t *packet_size, size_t max_packet_size)
+{
+       int rc = 0;
+       size_t body_size;
+       size_t length_size;
+
+       (*packet_size) = 0;
+       (*tag_11_contents_size) = 0;
+
+       /* check that:
+        *   one byte for the Tag 11 ID flag
+        *   two bytes for the Tag 11 length
+        * do not exceed the maximum_packet_size
+        */
+       if (unlikely((*packet_size) + 3 > max_packet_size)) {
+               ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* check for Tag 11 identifyer - one byte */
+       if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) {
+               ecryptfs_printk(KERN_WARNING,
+                               "Invalid tag 11 packet format\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* get Tag 11 content length - one or two bytes */
+       rc = parse_packet_length(&data[(*packet_size)], &body_size,
+                                &length_size);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING,
+                               "Invalid tag 11 packet format\n");
+               goto out;
+       }
+       (*packet_size) += length_size;
+
+       if (body_size < 13) {
+               ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
+                               body_size);
+               rc = -EINVAL;
+               goto out;
+       }
+       /* We have 13 bytes of surrounding packet values */
+       (*tag_11_contents_size) = (body_size - 13);
+
+       /* now we know the length of the remainting Tag 11 packet size:
+        *   14 fix bytes for: special flag one, special flag two,
+        *                     12 skipped bytes
+        *   body_size bytes minus the stuff above is the Tag 11 content
+        */
+       /* FIXME why is the body size one byte smaller than the actual
+        * size of the body?
+        * this seems to be an error here as well as in
+        * write_tag_11_packet() */
+       if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
+               ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* special flag one - one byte */
+       if (data[(*packet_size)++] != 0x62) {
+               ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* special flag two - one byte */
+       if (data[(*packet_size)++] != 0x08) {
+               ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* skip the next 12 bytes */
+       (*packet_size) += 12; /* We don't care about the filename or
+                              * the timestamp */
+
+       /* get the Tag 11 contents - tag_11_contents_size bytes */
+       memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size));
+       (*packet_size) += (*tag_11_contents_size);
+
+out:
+       if (rc) {
+               (*packet_size) = 0;
+               (*tag_11_contents_size) = 0;
+       }
+       return rc;
+}
+
+/**
+ * decrypt_session_key - Decrypt the session key with the given auth_tok.
+ *
+ * Returns Zero on success; non-zero error otherwise.
+ */
+static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
+                              struct ecryptfs_crypt_stat *crypt_stat)
+{
+       int rc = 0;
+       struct ecryptfs_password *password_s_ptr;
+       struct crypto_tfm *tfm = NULL;
+       struct scatterlist src_sg[2], dst_sg[2];
+       struct mutex *tfm_mutex = NULL;
+       /* TODO: Use virt_to_scatterlist for these */
+       char *encrypted_session_key;
+       char *session_key;
+
+       password_s_ptr = &auth_tok->token.password;
+       if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
+                               ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET))
+               ecryptfs_printk(KERN_DEBUG, "Session key encryption key "
+                               "set; skipping key generation\n");
+       ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])"
+                       ":\n",
+                       password_s_ptr->session_key_encryption_key_bytes);
+       if (ecryptfs_verbosity > 0)
+               ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key,
+                                 password_s_ptr->
+                                 session_key_encryption_key_bytes);
+       if (!strcmp(crypt_stat->cipher,
+                   crypt_stat->mount_crypt_stat->global_default_cipher_name)
+           && crypt_stat->mount_crypt_stat->global_key_tfm) {
+               tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+               tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+       } else {
+               tfm = crypto_alloc_tfm(crypt_stat->cipher,
+                                      CRYPTO_TFM_REQ_WEAK_KEY);
+               if (!tfm) {
+                       printk(KERN_ERR "Error allocating crypto context\n");
+                       rc = -ENOMEM;
+                       goto out;
+               }
+       }
+       if (password_s_ptr->session_key_encryption_key_bytes
+           < crypto_tfm_alg_min_keysize(tfm)) {
+               printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
+                      "minimum keysize for selected cipher is [%d] bytes.\n",
+                      password_s_ptr->session_key_encryption_key_bytes,
+                      crypto_tfm_alg_min_keysize(tfm));
+               rc = -EINVAL;
+               goto out;
+       }
+       if (tfm_mutex)
+               mutex_lock(tfm_mutex);
+       crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
+                            crypt_stat->key_size);
+       /* TODO: virt_to_scatterlist */
+       encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
+       if (!encrypted_session_key) {
+               ecryptfs_printk(KERN_ERR, "Out of memory\n");
+               rc = -ENOMEM;
+               goto out_free_tfm;
+       }
+       session_key = (char *)__get_free_page(GFP_KERNEL);
+       if (!session_key) {
+               kfree(encrypted_session_key);
+               ecryptfs_printk(KERN_ERR, "Out of memory\n");
+               rc = -ENOMEM;
+               goto out_free_tfm;
+       }
+       memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key,
+              auth_tok->session_key.encrypted_key_size);
+       src_sg[0].page = virt_to_page(encrypted_session_key);
+       src_sg[0].offset = 0;
+       BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE);
+       src_sg[0].length = auth_tok->session_key.encrypted_key_size;
+       dst_sg[0].page = virt_to_page(session_key);
+       dst_sg[0].offset = 0;
+       auth_tok->session_key.decrypted_key_size =
+           auth_tok->session_key.encrypted_key_size;
+       dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
+       /* TODO: Handle error condition */
+       crypto_cipher_decrypt(tfm, dst_sg, src_sg,
+                             auth_tok->session_key.encrypted_key_size);
+       auth_tok->session_key.decrypted_key_size =
+           auth_tok->session_key.encrypted_key_size;
+       memcpy(auth_tok->session_key.decrypted_key, session_key,
+              auth_tok->session_key.decrypted_key_size);
+       auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY;
+       memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
+              auth_tok->session_key.decrypted_key_size);
+       ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+       ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
+       if (ecryptfs_verbosity > 0)
+               ecryptfs_dump_hex(crypt_stat->key,
+                                 crypt_stat->key_size);
+       memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
+       free_page((unsigned long)encrypted_session_key);
+       memset(session_key, 0, PAGE_CACHE_SIZE);
+       free_page((unsigned long)session_key);
+out_free_tfm:
+       if (tfm_mutex)
+               mutex_unlock(tfm_mutex);
+       else
+               crypto_free_tfm(tfm);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_parse_packet_set
+ * @dest: The header page in memory
+ * @version: Version of file format, to guide parsing behavior
+ *
+ * Get crypt_stat to have the file's session key if the requisite key
+ * is available to decrypt the session key.
+ *
+ * Returns Zero if a valid authentication token was retrieved and
+ * processed; negative value for file not encrypted or for error
+ * conditions.
+ */
+int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
+                             unsigned char *src,
+                             struct dentry *ecryptfs_dentry)
+{
+       size_t i = 0;
+       int rc = 0;
+       size_t found_auth_tok = 0;
+       size_t next_packet_is_auth_tok_packet;
+       char sig[ECRYPTFS_SIG_SIZE_HEX];
+       struct list_head auth_tok_list;
+       struct list_head *walker;
+       struct ecryptfs_auth_tok *chosen_auth_tok = NULL;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+               &ecryptfs_superblock_to_private(
+                       ecryptfs_dentry->d_sb)->mount_crypt_stat;
+       struct ecryptfs_auth_tok *candidate_auth_tok = NULL;
+       size_t packet_size;
+       struct ecryptfs_auth_tok *new_auth_tok;
+       unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE];
+       size_t tag_11_contents_size;
+       size_t tag_11_packet_size;
+
+       INIT_LIST_HEAD(&auth_tok_list);
+       /* Parse the header to find as many packets as we can, these will be
+        * added the our &auth_tok_list */
+       next_packet_is_auth_tok_packet = 1;
+       while (next_packet_is_auth_tok_packet) {
+               size_t max_packet_size = ((PAGE_CACHE_SIZE - 8) - i);
+
+               switch (src[i]) {
+               case ECRYPTFS_TAG_3_PACKET_TYPE:
+                       rc = parse_tag_3_packet(crypt_stat,
+                                               (unsigned char *)&src[i],
+                                               &auth_tok_list, &new_auth_tok,
+                                               &packet_size, max_packet_size);
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "Error parsing "
+                                               "tag 3 packet\n");
+                               rc = -EIO;
+                               goto out_wipe_list;
+                       }
+                       i += packet_size;
+                       rc = parse_tag_11_packet((unsigned char *)&src[i],
+                                                sig_tmp_space,
+                                                ECRYPTFS_SIG_SIZE,
+                                                &tag_11_contents_size,
+                                                &tag_11_packet_size,
+                                                max_packet_size);
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "No valid "
+                                               "(ecryptfs-specific) literal "
+                                               "packet containing "
+                                               "authentication token "
+                                               "signature found after "
+                                               "tag 3 packet\n");
+                               rc = -EIO;
+                               goto out_wipe_list;
+                       }
+                       i += tag_11_packet_size;
+                       if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) {
+                               ecryptfs_printk(KERN_ERR, "Expected "
+                                               "signature of size [%d]; "
+                                               "read size [%d]\n",
+                                               ECRYPTFS_SIG_SIZE,
+                                               tag_11_contents_size);
+                               rc = -EIO;
+                               goto out_wipe_list;
+                       }
+                       ecryptfs_to_hex(new_auth_tok->token.password.signature,
+                                       sig_tmp_space, tag_11_contents_size);
+                       new_auth_tok->token.password.signature[
+                               ECRYPTFS_PASSWORD_SIG_SIZE] = '\0';
+                       ECRYPTFS_SET_FLAG(crypt_stat->flags,
+                                         ECRYPTFS_ENCRYPTED);
+                       break;
+               case ECRYPTFS_TAG_11_PACKET_TYPE:
+                       ecryptfs_printk(KERN_WARNING, "Invalid packet set "
+                                       "(Tag 11 not allowed by itself)\n");
+                       rc = -EIO;
+                       goto out_wipe_list;
+                       break;
+               default:
+                       ecryptfs_printk(KERN_DEBUG, "No packet at offset "
+                                       "[%d] of the file header; hex value of "
+                                       "character is [0x%.2x]\n", i, src[i]);
+                       next_packet_is_auth_tok_packet = 0;
+               }
+       }
+       if (list_empty(&auth_tok_list)) {
+               rc = -EINVAL; /* Do not support non-encrypted files in
+                              * the 0.1 release */
+               goto out;
+       }
+       /* If we have a global auth tok, then we should try to use
+        * it */
+       if (mount_crypt_stat->global_auth_tok) {
+               memcpy(sig, mount_crypt_stat->global_auth_tok_sig,
+                      ECRYPTFS_SIG_SIZE_HEX);
+               chosen_auth_tok = mount_crypt_stat->global_auth_tok;
+       } else
+               BUG(); /* We should always have a global auth tok in
+                       * the 0.1 release */
+       /* Scan list to see if our chosen_auth_tok works */
+       list_for_each(walker, &auth_tok_list) {
+               struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+               auth_tok_list_item =
+                   list_entry(walker, struct ecryptfs_auth_tok_list_item,
+                              list);
+               candidate_auth_tok = &auth_tok_list_item->auth_tok;
+               if (unlikely(ecryptfs_verbosity > 0)) {
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "Considering cadidate auth tok:\n");
+                       ecryptfs_dump_auth_tok(candidate_auth_tok);
+               }
+               /* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */
+               if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD
+                   && !strncmp(candidate_auth_tok->token.password.signature,
+                               sig, ECRYPTFS_SIG_SIZE_HEX)) {
+                       found_auth_tok = 1;
+                       goto leave_list;
+                       /* TODO: Transfer the common salt into the
+                        * crypt_stat salt */
+               }
+       }
+leave_list:
+       if (!found_auth_tok) {
+               ecryptfs_printk(KERN_ERR, "Could not find authentication "
+                               "token on temporary list for sig [%.*s]\n",
+                               ECRYPTFS_SIG_SIZE_HEX, sig);
+               rc = -EIO;
+               goto out_wipe_list;
+       } else {
+               memcpy(&(candidate_auth_tok->token.password),
+                      &(chosen_auth_tok->token.password),
+                      sizeof(struct ecryptfs_password));
+               rc = decrypt_session_key(candidate_auth_tok, crypt_stat);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error decrypting the "
+                                       "session key\n");
+                       goto out_wipe_list;
+               }
+               rc = ecryptfs_compute_root_iv(crypt_stat);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error computing "
+                                       "the root IV\n");
+                       goto out_wipe_list;
+               }
+       }
+       rc = ecryptfs_init_crypt_ctx(crypt_stat);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error initializing crypto "
+                               "context for cipher [%s]; rc = [%d]\n",
+                               crypt_stat->cipher, rc);
+       }
+out_wipe_list:
+       wipe_auth_tok_list(&auth_tok_list);
+out:
+       return rc;
+}
+
+/**
+ * write_tag_11_packet
+ * @dest: Target into which Tag 11 packet is to be written
+ * @max: Maximum packet length
+ * @contents: Byte array of contents to copy in
+ * @contents_length: Number of bytes in contents
+ * @packet_length: Length of the Tag 11 packet written; zero on error
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length,
+                   size_t *packet_length)
+{
+       int rc = 0;
+       size_t packet_size_length;
+
+       (*packet_length) = 0;
+       if ((13 + contents_length) > max) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_ERR, "Packet length larger than "
+                               "maximum allowable\n");
+               goto out;
+       }
+       /* General packet header */
+       /* Packet tag */
+       dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;
+       /* Packet length */
+       rc = write_packet_length(&dest[(*packet_length)],
+                                (13 + contents_length), &packet_size_length);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error generating tag 11 packet "
+                               "header; cannot generate packet length\n");
+               goto out;
+       }
+       (*packet_length) += packet_size_length;
+       /* Tag 11 specific */
+       /* One-octet field that describes how the data is formatted */
+       dest[(*packet_length)++] = 0x62; /* binary data */
+       /* One-octet filename length followed by filename */
+       dest[(*packet_length)++] = 8;
+       memcpy(&dest[(*packet_length)], "_CONSOLE", 8);
+       (*packet_length) += 8;
+       /* Four-octet number indicating modification date */
+       memset(&dest[(*packet_length)], 0x00, 4);
+       (*packet_length) += 4;
+       /* Remainder is literal data */
+       memcpy(&dest[(*packet_length)], contents, contents_length);
+       (*packet_length) += contents_length;
+ out:
+       if (rc)
+               (*packet_length) = 0;
+       return rc;
+}
+
+/**
+ * write_tag_3_packet
+ * @dest: Buffer into which to write the packet
+ * @max: Maximum number of bytes that can be written
+ * @auth_tok: Authentication token
+ * @crypt_stat: The cryptographic context
+ * @key_rec: encrypted key
+ * @packet_size: This function will write the number of bytes that end
+ *               up constituting the packet; set to zero on error
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int
+write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
+                  struct ecryptfs_crypt_stat *crypt_stat,
+                  struct ecryptfs_key_record *key_rec, size_t *packet_size)
+{
+       int rc = 0;
+
+       size_t i;
+       size_t signature_is_valid = 0;
+       size_t encrypted_session_key_valid = 0;
+       char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+       struct scatterlist dest_sg[2];
+       struct scatterlist src_sg[2];
+       struct crypto_tfm *tfm = NULL;
+       struct mutex *tfm_mutex = NULL;
+       size_t key_rec_size;
+       size_t packet_size_length;
+       size_t cipher_code;
+
+       (*packet_size) = 0;
+       /* Check for a valid signature on the auth_tok */
+       for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++)
+               signature_is_valid |= auth_tok->token.password.signature[i];
+       if (!signature_is_valid)
+               BUG();
+       ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature,
+                         ECRYPTFS_SIG_SIZE);
+       encrypted_session_key_valid = 0;
+       for (i = 0; i < crypt_stat->key_size; i++)
+               encrypted_session_key_valid |=
+                       auth_tok->session_key.encrypted_key[i];
+       if (encrypted_session_key_valid) {
+               memcpy((*key_rec).enc_key,
+                      auth_tok->session_key.encrypted_key,
+                      auth_tok->session_key.encrypted_key_size);
+               goto encrypted_session_key_set;
+       }
+       if (auth_tok->session_key.encrypted_key_size == 0)
+               auth_tok->session_key.encrypted_key_size =
+                       crypt_stat->key_size;
+       if (crypt_stat->key_size == 24
+           && strcmp("aes", crypt_stat->cipher) == 0) {
+               memset((crypt_stat->key + 24), 0, 8);
+               auth_tok->session_key.encrypted_key_size = 32;
+       }
+       (*key_rec).enc_key_size =
+               auth_tok->session_key.encrypted_key_size;
+       if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
+                               ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
+               ecryptfs_printk(KERN_DEBUG, "Using previously generated "
+                               "session key encryption key of size [%d]\n",
+                               auth_tok->token.password.
+                               session_key_encryption_key_bytes);
+               memcpy(session_key_encryption_key,
+                      auth_tok->token.password.session_key_encryption_key,
+                      crypt_stat->key_size);
+               ecryptfs_printk(KERN_DEBUG,
+                               "Cached session key " "encryption key: \n");
+               if (ecryptfs_verbosity > 0)
+                       ecryptfs_dump_hex(session_key_encryption_key, 16);
+       }
+       if (unlikely(ecryptfs_verbosity > 0)) {
+               ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");
+               ecryptfs_dump_hex(session_key_encryption_key, 16);
+       }
+       rc = virt_to_scatterlist(crypt_stat->key,
+                                (*key_rec).enc_key_size, src_sg, 2);
+       if (!rc) {
+               ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+                               "for crypt_stat session key\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       rc = virt_to_scatterlist((*key_rec).enc_key,
+                                (*key_rec).enc_key_size, dest_sg, 2);
+       if (!rc) {
+               ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
+                               "for crypt_stat encrypted session key\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       if (!strcmp(crypt_stat->cipher,
+                   crypt_stat->mount_crypt_stat->global_default_cipher_name)
+           && crypt_stat->mount_crypt_stat->global_key_tfm) {
+               tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+               tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+       } else
+               tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
+       if (!tfm) {
+               ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
+                               "context for cipher [%s]\n",
+                               crypt_stat->cipher);
+               rc = -EINVAL;
+               goto out;
+       }
+       if (tfm_mutex)
+               mutex_lock(tfm_mutex);
+       rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
+                                 crypt_stat->key_size);
+       if (rc < 0) {
+               if (tfm_mutex)
+                       mutex_unlock(tfm_mutex);
+               ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
+                               "context\n");
+               goto out;
+       }
+       rc = 0;
+       ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
+                       crypt_stat->key_size);
+       crypto_cipher_encrypt(tfm, dest_sg, src_sg,
+                             (*key_rec).enc_key_size);
+       if (tfm_mutex)
+               mutex_unlock(tfm_mutex);
+       ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
+       if (ecryptfs_verbosity > 0)
+               ecryptfs_dump_hex((*key_rec).enc_key,
+                                 (*key_rec).enc_key_size);
+encrypted_session_key_set:
+       /* Now we have a valid key_rec.  Append it to the
+        * key_rec set. */
+       key_rec_size = (sizeof(struct ecryptfs_key_record)
+                       - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
+                       + ((*key_rec).enc_key_size));
+       /* TODO: Include a packet size limit as a parameter to this
+        * function once we have multi-packet headers (for versions
+        * later than 0.1 */
+       if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) {
+               ecryptfs_printk(KERN_ERR, "Keyset too large\n");
+               rc = -EINVAL;
+               goto out;
+       }
+       /* TODO: Packet size limit */
+       /* We have 5 bytes of surrounding packet data */
+       if ((0x05 + ECRYPTFS_SALT_SIZE
+            + (*key_rec).enc_key_size) >= max) {
+               ecryptfs_printk(KERN_ERR, "Authentication token is too "
+                               "large\n");
+               rc = -EINVAL;
+               goto out;
+       }
+       /* This format is inspired by OpenPGP; see RFC 2440
+        * packet tag 3 */
+       dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;
+       /* ver+cipher+s2k+hash+salt+iter+enc_key */
+       rc = write_packet_length(&dest[(*packet_size)],
+                                (0x05 + ECRYPTFS_SALT_SIZE
+                                 + (*key_rec).enc_key_size),
+                                &packet_size_length);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet "
+                               "header; cannot generate packet length\n");
+               goto out;
+       }
+       (*packet_size) += packet_size_length;
+       dest[(*packet_size)++] = 0x04; /* version 4 */
+       cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);
+       if (cipher_code == 0) {
+               ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
+                               "cipher [%s]\n", crypt_stat->cipher);
+               rc = -EINVAL;
+               goto out;
+       }
+       dest[(*packet_size)++] = cipher_code;
+       dest[(*packet_size)++] = 0x03;  /* S2K */
+       dest[(*packet_size)++] = 0x01;  /* MD5 (TODO: parameterize) */
+       memcpy(&dest[(*packet_size)], auth_tok->token.password.salt,
+              ECRYPTFS_SALT_SIZE);
+       (*packet_size) += ECRYPTFS_SALT_SIZE;   /* salt */
+       dest[(*packet_size)++] = 0x60;  /* hash iterations (65536) */
+       memcpy(&dest[(*packet_size)], (*key_rec).enc_key,
+              (*key_rec).enc_key_size);
+       (*packet_size) += (*key_rec).enc_key_size;
+out:
+       if (tfm && !tfm_mutex)
+               crypto_free_tfm(tfm);
+       if (rc)
+               (*packet_size) = 0;
+       return rc;
+}
+
+/**
+ * ecryptfs_generate_key_packet_set
+ * @dest: Virtual address from which to write the key record set
+ * @crypt_stat: The cryptographic context from which the
+ *              authentication tokens will be retrieved
+ * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat
+ *                   for the global parameters
+ * @len: The amount written
+ * @max: The maximum amount of data allowed to be written
+ *
+ * Generates a key packet set and writes it to the virtual address
+ * passed in.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+int
+ecryptfs_generate_key_packet_set(char *dest_base,
+                                struct ecryptfs_crypt_stat *crypt_stat,
+                                struct dentry *ecryptfs_dentry, size_t *len,
+                                size_t max)
+{
+       int rc = 0;
+       struct ecryptfs_auth_tok *auth_tok;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+               &ecryptfs_superblock_to_private(
+                       ecryptfs_dentry->d_sb)->mount_crypt_stat;
+       size_t written;
+       struct ecryptfs_key_record key_rec;
+
+       (*len) = 0;
+       if (mount_crypt_stat->global_auth_tok) {
+               auth_tok = mount_crypt_stat->global_auth_tok;
+               if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
+                       rc = write_tag_3_packet((dest_base + (*len)),
+                                               max, auth_tok,
+                                               crypt_stat, &key_rec,
+                                               &written);
+                       if (rc) {
+                               ecryptfs_printk(KERN_WARNING, "Error "
+                                               "writing tag 3 packet\n");
+                               goto out;
+                       }
+                       (*len) += written;
+                       /* Write auth tok signature packet */
+                       rc = write_tag_11_packet(
+                               (dest_base + (*len)),
+                               (max - (*len)),
+                               key_rec.sig, ECRYPTFS_SIG_SIZE, &written);
+                       if (rc) {
+                               ecryptfs_printk(KERN_ERR, "Error writing "
+                                               "auth tok signature packet\n");
+                               goto out;
+                       }
+                       (*len) += written;
+               } else {
+                       ecryptfs_printk(KERN_WARNING, "Unsupported "
+                                       "authentication token type\n");
+                       rc = -EINVAL;
+                       goto out;
+               }
+               if (rc) {
+                       ecryptfs_printk(KERN_WARNING, "Error writing "
+                                       "authentication token packet with sig "
+                                       "= [%s]\n",
+                                       mount_crypt_stat->global_auth_tok_sig);
+                       rc = -EIO;
+                       goto out;
+               }
+       } else
+               BUG();
+       if (likely((max - (*len)) > 0)) {
+               dest_base[(*len)] = 0x00;
+       } else {
+               ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
+               rc = -EIO;
+       }
+out:
+       if (rc)
+               (*len) = 0;
+       return rc;
+}
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
new file mode 100644 (file)
index 0000000..7a11b8a
--- /dev/null
@@ -0,0 +1,831 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/dcache.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/skbuff.h>
+#include <linux/crypto.h>
+#include <linux/netlink.h>
+#include <linux/mount.h>
+#include <linux/dcache.h>
+#include <linux/pagemap.h>
+#include <linux/key.h>
+#include <linux/parser.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * Module parameter that defines the ecryptfs_verbosity level.
+ */
+int ecryptfs_verbosity = 0;
+
+module_param(ecryptfs_verbosity, int, 0);
+MODULE_PARM_DESC(ecryptfs_verbosity,
+                "Initial verbosity level (0 or 1; defaults to "
+                "0, which is Quiet)");
+
+void __ecryptfs_printk(const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       if (fmt[1] == '7') { /* KERN_DEBUG */
+               if (ecryptfs_verbosity >= 1)
+                       vprintk(fmt, args);
+       } else
+               vprintk(fmt, args);
+       va_end(args);
+}
+
+/**
+ * ecryptfs_interpose
+ * @lower_dentry: Existing dentry in the lower filesystem
+ * @dentry: ecryptfs' dentry
+ * @sb: ecryptfs's super_block
+ * @flag: If set to true, then d_add is called, else d_instantiate is called
+ *
+ * Interposes upper and lower dentries.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
+                      struct super_block *sb, int flag)
+{
+       struct inode *lower_inode;
+       struct inode *inode;
+       int rc = 0;
+
+       lower_inode = lower_dentry->d_inode;
+       if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) {
+               rc = -EXDEV;
+               goto out;
+       }
+       if (!igrab(lower_inode)) {
+               rc = -ESTALE;
+               goto out;
+       }
+       inode = iget5_locked(sb, (unsigned long)lower_inode,
+                            ecryptfs_inode_test, ecryptfs_inode_set,
+                            lower_inode);
+       if (!inode) {
+               rc = -EACCES;
+               iput(lower_inode);
+               goto out;
+       }
+       if (inode->i_state & I_NEW)
+               unlock_new_inode(inode);
+       else
+               iput(lower_inode);
+       if (S_ISLNK(lower_inode->i_mode))
+               inode->i_op = &ecryptfs_symlink_iops;
+       else if (S_ISDIR(lower_inode->i_mode))
+               inode->i_op = &ecryptfs_dir_iops;
+       if (S_ISDIR(lower_inode->i_mode))
+               inode->i_fop = &ecryptfs_dir_fops;
+       /* TODO: Is there a better way to identify if the inode is
+        * special? */
+       if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
+           S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
+               init_special_inode(inode, lower_inode->i_mode,
+                                  lower_inode->i_rdev);
+       dentry->d_op = &ecryptfs_dops;
+       if (flag)
+               d_add(dentry, inode);
+       else
+               d_instantiate(dentry, inode);
+       ecryptfs_copy_attr_all(inode, lower_inode);
+       /* This size will be overwritten for real files w/ headers and
+        * other metadata */
+       ecryptfs_copy_inode_size(inode, lower_inode);
+out:
+       return rc;
+}
+
+enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug,
+       ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher,
+       ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes,
+       ecryptfs_opt_passthrough, ecryptfs_opt_err };
+
+static match_table_t tokens = {
+       {ecryptfs_opt_sig, "sig=%s"},
+       {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"},
+       {ecryptfs_opt_debug, "debug=%u"},
+       {ecryptfs_opt_ecryptfs_debug, "ecryptfs_debug=%u"},
+       {ecryptfs_opt_cipher, "cipher=%s"},
+       {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"},
+       {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"},
+       {ecryptfs_opt_passthrough, "ecryptfs_passthrough"},
+       {ecryptfs_opt_err, NULL}
+};
+
+/**
+ * ecryptfs_verify_version
+ * @version: The version number to confirm
+ *
+ * Returns zero on good version; non-zero otherwise
+ */
+static int ecryptfs_verify_version(u16 version)
+{
+       int rc = 0;
+       unsigned char major;
+       unsigned char minor;
+
+       major = ((version >> 8) & 0xFF);
+       minor = (version & 0xFF);
+       if (major != ECRYPTFS_VERSION_MAJOR) {
+               ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
+                               "Expected [%d]; got [%d]\n",
+                               ECRYPTFS_VERSION_MAJOR, major);
+               rc = -EINVAL;
+               goto out;
+       }
+       if (minor != ECRYPTFS_VERSION_MINOR) {
+               ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
+                               "Expected [%d]; got [%d]\n",
+                               ECRYPTFS_VERSION_MINOR, minor);
+               rc = -EINVAL;
+               goto out;
+       }
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_parse_options
+ * @sb: The ecryptfs super block
+ * @options: The options pased to the kernel
+ *
+ * Parse mount options:
+ * debug=N        - ecryptfs_verbosity level for debug output
+ * sig=XXX        - description(signature) of the key to use
+ *
+ * Returns the dentry object of the lower-level (lower/interposed)
+ * directory; We want to mount our stackable file system on top of
+ * that lower directory.
+ *
+ * The signature of the key to use must be the description of a key
+ * already in the keyring. Mounting will fail if the key can not be
+ * found.
+ *
+ * Returns zero on success; non-zero on error
+ */
+static int ecryptfs_parse_options(struct super_block *sb, char *options)
+{
+       char *p;
+       int rc = 0;
+       int sig_set = 0;
+       int cipher_name_set = 0;
+       int cipher_key_bytes;
+       int cipher_key_bytes_set = 0;
+       struct key *auth_tok_key = NULL;
+       struct ecryptfs_auth_tok *auth_tok = NULL;
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+               &ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
+       substring_t args[MAX_OPT_ARGS];
+       int token;
+       char *sig_src;
+       char *sig_dst;
+       char *debug_src;
+       char *cipher_name_dst;
+       char *cipher_name_src;
+       char *cipher_key_bytes_src;
+       struct crypto_tfm *tmp_tfm;
+       int cipher_name_len;
+
+       if (!options) {
+               rc = -EINVAL;
+               goto out;
+       }
+       while ((p = strsep(&options, ",")) != NULL) {
+               if (!*p)
+                       continue;
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case ecryptfs_opt_sig:
+               case ecryptfs_opt_ecryptfs_sig:
+                       sig_src = args[0].from;
+                       sig_dst =
+                               mount_crypt_stat->global_auth_tok_sig;
+                       memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX);
+                       sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "The mount_crypt_stat "
+                                       "global_auth_tok_sig set to: "
+                                       "[%s]\n", sig_dst);
+                       sig_set = 1;
+                       break;
+               case ecryptfs_opt_debug:
+               case ecryptfs_opt_ecryptfs_debug:
+                       debug_src = args[0].from;
+                       ecryptfs_verbosity =
+                               (int)simple_strtol(debug_src, &debug_src,
+                                                  0);
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "Verbosity set to [%d]" "\n",
+                                       ecryptfs_verbosity);
+                       break;
+               case ecryptfs_opt_cipher:
+               case ecryptfs_opt_ecryptfs_cipher:
+                       cipher_name_src = args[0].from;
+                       cipher_name_dst =
+                               mount_crypt_stat->
+                               global_default_cipher_name;
+                       strncpy(cipher_name_dst, cipher_name_src,
+                               ECRYPTFS_MAX_CIPHER_NAME_SIZE);
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "The mount_crypt_stat "
+                                       "global_default_cipher_name set to: "
+                                       "[%s]\n", cipher_name_dst);
+                       cipher_name_set = 1;
+                       break;
+               case ecryptfs_opt_ecryptfs_key_bytes:
+                       cipher_key_bytes_src = args[0].from;
+                       cipher_key_bytes =
+                               (int)simple_strtol(cipher_key_bytes_src,
+                                                  &cipher_key_bytes_src, 0);
+                       mount_crypt_stat->global_default_cipher_key_size =
+                               cipher_key_bytes;
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "The mount_crypt_stat "
+                                       "global_default_cipher_key_size "
+                                       "set to: [%d]\n", mount_crypt_stat->
+                                       global_default_cipher_key_size);
+                       cipher_key_bytes_set = 1;
+                       break;
+               case ecryptfs_opt_passthrough:
+                       mount_crypt_stat->flags |=
+                               ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED;
+                       break;
+               case ecryptfs_opt_err:
+               default:
+                       ecryptfs_printk(KERN_WARNING,
+                                       "eCryptfs: unrecognized option '%s'\n",
+                                       p);
+               }
+       }
+       /* Do not support lack of mount-wide signature in 0.1
+        * release */
+       if (!sig_set) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_ERR, "You must supply a valid "
+                               "passphrase auth tok signature as a mount "
+                               "parameter; see the eCryptfs README\n");
+               goto out;
+       }
+       if (!cipher_name_set) {
+               cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER);
+               if (unlikely(cipher_name_len
+                            >= ECRYPTFS_MAX_CIPHER_NAME_SIZE)) {
+                       rc = -EINVAL;
+                       BUG();
+                       goto out;
+               }
+               memcpy(mount_crypt_stat->global_default_cipher_name,
+                      ECRYPTFS_DEFAULT_CIPHER, cipher_name_len);
+               mount_crypt_stat->global_default_cipher_name[cipher_name_len]
+                   = '\0';
+       }
+       if (!cipher_key_bytes_set) {
+               mount_crypt_stat->global_default_cipher_key_size =
+                       ECRYPTFS_DEFAULT_KEY_BYTES;
+               ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
+                               "specified.  Defaulting to [%d]\n",
+                               mount_crypt_stat->
+                               global_default_cipher_key_size);
+       }
+       rc = ecryptfs_process_cipher(
+               &tmp_tfm,
+               &mount_crypt_stat->global_key_tfm,
+               mount_crypt_stat->global_default_cipher_name,
+               mount_crypt_stat->global_default_cipher_key_size);
+       if (tmp_tfm)
+               crypto_free_tfm(tmp_tfm);
+       if (rc) {
+               printk(KERN_ERR "Error attempting to initialize cipher [%s] "
+                      "with key size [%Zd] bytes; rc = [%d]\n",
+                      mount_crypt_stat->global_default_cipher_name,
+                      mount_crypt_stat->global_default_cipher_key_size, rc);
+               rc = -EINVAL;
+               goto out;
+       }
+       mutex_init(&mount_crypt_stat->global_key_tfm_mutex);
+       ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
+                       "[%s]\n", mount_crypt_stat->global_auth_tok_sig);
+       /* The reference to this key is held until umount is done The
+        * call to key_put is done in ecryptfs_put_super() */
+       auth_tok_key = request_key(&key_type_user,
+                                  mount_crypt_stat->global_auth_tok_sig,
+                                  NULL);
+       if (!auth_tok_key || IS_ERR(auth_tok_key)) {
+               ecryptfs_printk(KERN_ERR, "Could not find key with "
+                               "description: [%s]\n",
+                               mount_crypt_stat->global_auth_tok_sig);
+               process_request_key_err(PTR_ERR(auth_tok_key));
+               rc = -EINVAL;
+               goto out;
+       }
+       auth_tok = ecryptfs_get_key_payload_data(auth_tok_key);
+       if (ecryptfs_verify_version(auth_tok->version)) {
+               ecryptfs_printk(KERN_ERR, "Data structure version mismatch. "
+                               "Userspace tools must match eCryptfs kernel "
+                               "module with major version [%d] and minor "
+                               "version [%d]\n", ECRYPTFS_VERSION_MAJOR,
+                               ECRYPTFS_VERSION_MINOR);
+               rc = -EINVAL;
+               goto out;
+       }
+       if (auth_tok->token_type != ECRYPTFS_PASSWORD) {
+               ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure "
+                               "returned from key\n");
+               rc = -EINVAL;
+               goto out;
+       }
+       mount_crypt_stat->global_auth_tok_key = auth_tok_key;
+       mount_crypt_stat->global_auth_tok = auth_tok;
+out:
+       return rc;
+}
+
+struct kmem_cache *ecryptfs_sb_info_cache;
+
+/**
+ * ecryptfs_fill_super
+ * @sb: The ecryptfs super block
+ * @raw_data: The options passed to mount
+ * @silent: Not used but required by function prototype
+ *
+ * Sets up what we can of the sb, rest is done in ecryptfs_read_super
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int
+ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
+{
+       int rc = 0;
+
+       /* Released in ecryptfs_put_super() */
+       ecryptfs_set_superblock_private(sb,
+                                       kmem_cache_alloc(ecryptfs_sb_info_cache,
+                                                        SLAB_KERNEL));
+       if (!ecryptfs_superblock_to_private(sb)) {
+               ecryptfs_printk(KERN_WARNING, "Out of memory\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       memset(ecryptfs_superblock_to_private(sb), 0,
+              sizeof(struct ecryptfs_sb_info));
+       sb->s_op = &ecryptfs_sops;
+       /* Released through deactivate_super(sb) from get_sb_nodev */
+       sb->s_root = d_alloc(NULL, &(const struct qstr) {
+                            .hash = 0,.name = "/",.len = 1});
+       if (!sb->s_root) {
+               ecryptfs_printk(KERN_ERR, "d_alloc failed\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       sb->s_root->d_op = &ecryptfs_dops;
+       sb->s_root->d_sb = sb;
+       sb->s_root->d_parent = sb->s_root;
+       /* Released in d_release when dput(sb->s_root) is called */
+       /* through deactivate_super(sb) from get_sb_nodev() */
+       ecryptfs_set_dentry_private(sb->s_root,
+                                   kmem_cache_alloc(ecryptfs_dentry_info_cache,
+                                                    SLAB_KERNEL));
+       if (!ecryptfs_dentry_to_private(sb->s_root)) {
+               ecryptfs_printk(KERN_ERR,
+                               "dentry_info_cache alloc failed\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+       memset(ecryptfs_dentry_to_private(sb->s_root), 0,
+              sizeof(struct ecryptfs_dentry_info));
+       rc = 0;
+out:
+       /* Should be able to rely on deactivate_super called from
+        * get_sb_nodev */
+       return rc;
+}
+
+/**
+ * ecryptfs_read_super
+ * @sb: The ecryptfs super block
+ * @dev_name: The path to mount over
+ *
+ * Read the super block of the lower filesystem, and use
+ * ecryptfs_interpose to create our initial inode and super block
+ * struct.
+ */
+static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
+{
+       int rc;
+       struct nameidata nd;
+       struct dentry *lower_root;
+       struct vfsmount *lower_mnt;
+
+       memset(&nd, 0, sizeof(struct nameidata));
+       rc = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
+               goto out_free;
+       }
+       lower_root = nd.dentry;
+       if (!lower_root->d_inode) {
+               ecryptfs_printk(KERN_WARNING,
+                               "No directory to interpose on\n");
+               rc = -ENOENT;
+               goto out_free;
+       }
+       lower_mnt = nd.mnt;
+       ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
+       sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
+       ecryptfs_set_dentry_lower(sb->s_root, lower_root);
+       ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
+       if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0)))
+               goto out_free;
+       rc = 0;
+       goto out;
+out_free:
+       path_release(&nd);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_get_sb
+ * @fs_type
+ * @flags
+ * @dev_name: The path to mount over
+ * @raw_data: The options passed into the kernel
+ *
+ * The whole ecryptfs_get_sb process is broken into 4 functions:
+ * ecryptfs_parse_options(): handle options passed to ecryptfs, if any
+ * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block
+ *                        with as much information as it can before needing
+ *                        the lower filesystem.
+ * ecryptfs_read_super(): this accesses the lower filesystem and uses
+ *                        ecryptfs_interpolate to perform most of the linking
+ * ecryptfs_interpolate(): links the lower filesystem into ecryptfs
+ */
+static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
+                       const char *dev_name, void *raw_data,
+                       struct vfsmount *mnt)
+{
+       int rc;
+       struct super_block *sb;
+
+       rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt);
+       if (rc < 0) {
+               printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc);
+               goto out;
+       }
+       sb = mnt->mnt_sb;
+       rc = ecryptfs_parse_options(sb, raw_data);
+       if (rc) {
+               printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc);
+               goto out_abort;
+       }
+       rc = ecryptfs_read_super(sb, dev_name);
+       if (rc) {
+               printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc);
+               goto out_abort;
+       }
+       goto out;
+out_abort:
+       dput(sb->s_root);
+       up_write(&sb->s_umount);
+       deactivate_super(sb);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_kill_block_super
+ * @sb: The ecryptfs super block
+ *
+ * Used to bring the superblock down and free the private data.
+ * Private data is free'd in ecryptfs_put_super()
+ */
+static void ecryptfs_kill_block_super(struct super_block *sb)
+{
+       generic_shutdown_super(sb);
+}
+
+static struct file_system_type ecryptfs_fs_type = {
+       .owner = THIS_MODULE,
+       .name = "ecryptfs",
+       .get_sb = ecryptfs_get_sb,
+       .kill_sb = ecryptfs_kill_block_super,
+       .fs_flags = 0
+};
+
+/**
+ * inode_info_init_once
+ *
+ * Initializes the ecryptfs_inode_info_cache when it is created
+ */
+static void
+inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
+{
+       struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr;
+
+       if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
+           SLAB_CTOR_CONSTRUCTOR)
+               inode_init_once(&ei->vfs_inode);
+}
+
+static struct ecryptfs_cache_info {
+       kmem_cache_t **cache;
+       const char *name;
+       size_t size;
+       void (*ctor)(void*, struct kmem_cache *, unsigned long);
+} ecryptfs_cache_infos[] = {
+       {
+               .cache = &ecryptfs_auth_tok_list_item_cache,
+               .name = "ecryptfs_auth_tok_list_item",
+               .size = sizeof(struct ecryptfs_auth_tok_list_item),
+       },
+       {
+               .cache = &ecryptfs_file_info_cache,
+               .name = "ecryptfs_file_cache",
+               .size = sizeof(struct ecryptfs_file_info),
+       },
+       {
+               .cache = &ecryptfs_dentry_info_cache,
+               .name = "ecryptfs_dentry_info_cache",
+               .size = sizeof(struct ecryptfs_dentry_info),
+       },
+       {
+               .cache = &ecryptfs_inode_info_cache,
+               .name = "ecryptfs_inode_cache",
+               .size = sizeof(struct ecryptfs_inode_info),
+               .ctor = inode_info_init_once,
+       },
+       {
+               .cache = &ecryptfs_sb_info_cache,
+               .name = "ecryptfs_sb_cache",
+               .size = sizeof(struct ecryptfs_sb_info),
+       },
+       {
+               .cache = &ecryptfs_header_cache_0,
+               .name = "ecryptfs_headers_0",
+               .size = PAGE_CACHE_SIZE,
+       },
+       {
+               .cache = &ecryptfs_header_cache_1,
+               .name = "ecryptfs_headers_1",
+               .size = PAGE_CACHE_SIZE,
+       },
+       {
+               .cache = &ecryptfs_header_cache_2,
+               .name = "ecryptfs_headers_2",
+               .size = PAGE_CACHE_SIZE,
+       },
+       {
+               .cache = &ecryptfs_lower_page_cache,
+               .name = "ecryptfs_lower_page_cache",
+               .size = PAGE_CACHE_SIZE,
+       },
+};
+
+static void ecryptfs_free_kmem_caches(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) {
+               struct ecryptfs_cache_info *info;
+
+               info = &ecryptfs_cache_infos[i];
+               if (*(info->cache))
+                       kmem_cache_destroy(*(info->cache));
+       }
+}
+
+/**
+ * ecryptfs_init_kmem_caches
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_init_kmem_caches(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) {
+               struct ecryptfs_cache_info *info;
+
+               info = &ecryptfs_cache_infos[i];
+               *(info->cache) = kmem_cache_create(info->name, info->size,
+                               0, SLAB_HWCACHE_ALIGN, info->ctor, NULL);
+               if (!*(info->cache)) {
+                       ecryptfs_free_kmem_caches();
+                       ecryptfs_printk(KERN_WARNING, "%s: "
+                                       "kmem_cache_create failed\n",
+                                       info->name);
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
+struct ecryptfs_obj {
+       char *name;
+       struct list_head slot_list;
+       struct kobject kobj;
+};
+
+struct ecryptfs_attribute {
+       struct attribute attr;
+       ssize_t(*show) (struct ecryptfs_obj *, char *);
+       ssize_t(*store) (struct ecryptfs_obj *, const char *, size_t);
+};
+
+static ssize_t
+ecryptfs_attr_store(struct kobject *kobj,
+                   struct attribute *attr, const char *buf, size_t len)
+{
+       struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj,
+                                               kobj);
+       struct ecryptfs_attribute *attribute =
+               container_of(attr, struct ecryptfs_attribute, attr);
+
+       return (attribute->store ? attribute->store(obj, buf, len) : 0);
+}
+
+static ssize_t
+ecryptfs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+       struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj,
+                                               kobj);
+       struct ecryptfs_attribute *attribute =
+               container_of(attr, struct ecryptfs_attribute, attr);
+
+       return (attribute->show ? attribute->show(obj, buf) : 0);
+}
+
+static struct sysfs_ops ecryptfs_sysfs_ops = {
+       .show = ecryptfs_attr_show,
+       .store = ecryptfs_attr_store
+};
+
+static struct kobj_type ecryptfs_ktype = {
+       .sysfs_ops = &ecryptfs_sysfs_ops
+};
+
+static decl_subsys(ecryptfs, &ecryptfs_ktype, NULL);
+
+static ssize_t version_show(struct ecryptfs_obj *obj, char *buff)
+{
+       return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK);
+}
+
+static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version);
+
+struct ecryptfs_version_str_map_elem {
+       u32 flag;
+       char *str;
+} ecryptfs_version_str_map[] = {
+       {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"},
+       {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"},
+       {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
+       {ECRYPTFS_VERSIONING_POLICY, "policy"}
+};
+
+static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff)
+{
+       int i;
+       int remaining = PAGE_SIZE;
+       int total_written = 0;
+
+       buff[0] = '\0';
+       for (i = 0; i < ARRAY_SIZE(ecryptfs_version_str_map); i++) {
+               int entry_size;
+
+               if (!(ECRYPTFS_VERSIONING_MASK
+                     & ecryptfs_version_str_map[i].flag))
+                       continue;
+               entry_size = strlen(ecryptfs_version_str_map[i].str);
+               if ((entry_size + 2) > remaining)
+                       goto out;
+               memcpy(buff, ecryptfs_version_str_map[i].str, entry_size);
+               buff[entry_size++] = '\n';
+               buff[entry_size] = '\0';
+               buff += entry_size;
+               total_written += entry_size;
+               remaining -= entry_size;
+       }
+out:
+       return total_written;
+}
+
+static struct ecryptfs_attribute sysfs_attr_version_str = __ATTR_RO(version_str);
+
+static int do_sysfs_registration(void)
+{
+       int rc;
+
+       if ((rc = subsystem_register(&ecryptfs_subsys))) {
+               printk(KERN_ERR
+                      "Unable to register ecryptfs sysfs subsystem\n");
+               goto out;
+       }
+       rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj,
+                              &sysfs_attr_version.attr);
+       if (rc) {
+               printk(KERN_ERR
+                      "Unable to create ecryptfs version attribute\n");
+               subsystem_unregister(&ecryptfs_subsys);
+               goto out;
+       }
+       rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj,
+                              &sysfs_attr_version_str.attr);
+       if (rc) {
+               printk(KERN_ERR
+                      "Unable to create ecryptfs version_str attribute\n");
+               sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+                                 &sysfs_attr_version.attr);
+               subsystem_unregister(&ecryptfs_subsys);
+               goto out;
+       }
+out:
+       return rc;
+}
+
+static int __init ecryptfs_init(void)
+{
+       int rc;
+
+       if (ECRYPTFS_DEFAULT_EXTENT_SIZE > PAGE_CACHE_SIZE) {
+               rc = -EINVAL;
+               ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is "
+                               "larger than the host's page size, and so "
+                               "eCryptfs cannot run on this system. The "
+                               "default eCryptfs extent size is [%d] bytes; "
+                               "the page size is [%d] bytes.\n",
+                               ECRYPTFS_DEFAULT_EXTENT_SIZE, PAGE_CACHE_SIZE);
+               goto out;
+       }
+       rc = ecryptfs_init_kmem_caches();
+       if (rc) {
+               printk(KERN_ERR
+                      "Failed to allocate one or more kmem_cache objects\n");
+               goto out;
+       }
+       rc = register_filesystem(&ecryptfs_fs_type);
+       if (rc) {
+               printk(KERN_ERR "Failed to register filesystem\n");
+               ecryptfs_free_kmem_caches();
+               goto out;
+       }
+       kset_set_kset_s(&ecryptfs_subsys, fs_subsys);
+       sysfs_attr_version.attr.owner = THIS_MODULE;
+       sysfs_attr_version_str.attr.owner = THIS_MODULE;
+       rc = do_sysfs_registration();
+       if (rc) {
+               printk(KERN_ERR "sysfs registration failed\n");
+               unregister_filesystem(&ecryptfs_fs_type);
+               ecryptfs_free_kmem_caches();
+               goto out;
+       }
+out:
+       return rc;
+}
+
+static void __exit ecryptfs_exit(void)
+{
+       sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+                         &sysfs_attr_version.attr);
+       sysfs_remove_file(&ecryptfs_subsys.kset.kobj,
+                         &sysfs_attr_version_str.attr);
+       subsystem_unregister(&ecryptfs_subsys);
+       unregister_filesystem(&ecryptfs_fs_type);
+       ecryptfs_free_kmem_caches();
+}
+
+MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>");
+MODULE_DESCRIPTION("eCryptfs");
+
+MODULE_LICENSE("GPL");
+
+module_init(ecryptfs_init)
+module_exit(ecryptfs_exit)
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
new file mode 100644 (file)
index 0000000..924dd90
--- /dev/null
@@ -0,0 +1,788 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ * This is where eCryptfs coordinates the symmetric encryption and
+ * decryption of the file data as it passes between the lower
+ * encrypted file and the upper decrypted file.
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/page-flags.h>
+#include <linux/mount.h>
+#include <linux/file.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include "ecryptfs_kernel.h"
+
+struct kmem_cache *ecryptfs_lower_page_cache;
+
+/**
+ * ecryptfs_get1page
+ *
+ * Get one page from cache or lower f/s, return error otherwise.
+ *
+ * Returns unlocked and up-to-date page (if ok), with increased
+ * refcnt.
+ */
+static struct page *ecryptfs_get1page(struct file *file, int index)
+{
+       struct page *page;
+       struct dentry *dentry;
+       struct inode *inode;
+       struct address_space *mapping;
+
+       dentry = file->f_dentry;
+       inode = dentry->d_inode;
+       mapping = inode->i_mapping;
+       page = read_cache_page(mapping, index,
+                              (filler_t *)mapping->a_ops->readpage,
+                              (void *)file);
+       if (IS_ERR(page))
+               goto out;
+       wait_on_page_locked(page);
+out:
+       return page;
+}
+
+static
+int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros);
+
+/**
+ * ecryptfs_fill_zeros
+ * @file: The ecryptfs file
+ * @new_length: The new length of the data in the underlying file;
+ *              everything between the prior end of the file and the
+ *              new end of the file will be filled with zero's.
+ *              new_length must be greater than  current length
+ *
+ * Function for handling lseek-ing past the end of the file.
+ *
+ * This function does not support shrinking, only growing a file.
+ *
+ * Returns zero on success; non-zero otherwise.
+ */
+int ecryptfs_fill_zeros(struct file *file, loff_t new_length)
+{
+       int rc = 0;
+       struct dentry *dentry = file->f_dentry;
+       struct inode *inode = dentry->d_inode;
+       pgoff_t old_end_page_index = 0;
+       pgoff_t index = old_end_page_index;
+       int old_end_pos_in_page = -1;
+       pgoff_t new_end_page_index;
+       int new_end_pos_in_page;
+       loff_t cur_length = i_size_read(inode);
+
+       if (cur_length != 0) {
+               index = old_end_page_index =
+                   ((cur_length - 1) >> PAGE_CACHE_SHIFT);
+               old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK);
+       }
+       new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
+       new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
+       ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; "
+                       "old_end_pos_in_page = [%d]; "
+                       "new_end_page_index = [0x%.16x]; "
+                       "new_end_pos_in_page = [%d]\n",
+                       old_end_page_index, old_end_pos_in_page,
+                       new_end_page_index, new_end_pos_in_page);
+       if (old_end_page_index == new_end_page_index) {
+               /* Start and end are in the same page; we just need to
+                * set a portion of the existing page to zero's */
+               rc = write_zeros(file, index, (old_end_pos_in_page + 1),
+                                (new_end_pos_in_page - old_end_pos_in_page));
+               if (rc)
+                       ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+                                       "index=[0x%.16x], "
+                                       "old_end_pos_in_page=[d], "
+                                       "(PAGE_CACHE_SIZE - new_end_pos_in_page"
+                                       "=[%d]"
+                                       ")=[d]) returned [%d]\n", file, index,
+                                       old_end_pos_in_page,
+                                       new_end_pos_in_page,
+                                       (PAGE_CACHE_SIZE - new_end_pos_in_page),
+                                       rc);
+               goto out;
+       }
+       /* Fill the remainder of the previous last page with zeros */
+       rc = write_zeros(file, index, (old_end_pos_in_page + 1),
+                        ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page));
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+                               "index=[0x%.16x], old_end_pos_in_page=[d], "
+                               "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) "
+                               "returned [%d]\n", file, index,
+                               old_end_pos_in_page,
+                               (PAGE_CACHE_SIZE - old_end_pos_in_page), rc);
+               goto out;
+       }
+       index++;
+       while (index < new_end_page_index) {
+               /* Fill all intermediate pages with zeros */
+               rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], "
+                                       "index=[0x%.16x], "
+                                       "old_end_pos_in_page=[d], "
+                                       "(PAGE_CACHE_SIZE - new_end_pos_in_page"
+                                       "=[%d]"
+                                       ")=[d]) returned [%d]\n", file, index,
+                                       old_end_pos_in_page,
+                                       new_end_pos_in_page,
+                                       (PAGE_CACHE_SIZE - new_end_pos_in_page),
+                                       rc);
+                       goto out;
+               }
+               index++;
+       }
+       /* Fill the portion at the beginning of the last new page with
+        * zero's */
+       rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1));
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "write_zeros(file="
+                               "[%p], index=[0x%.16x], 0, "
+                               "new_end_pos_in_page=[%d]"
+                               "returned [%d]\n", file, index,
+                               new_end_pos_in_page, rc);
+               goto out;
+       }
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_writepage
+ * @page: Page that is locked before this call is made
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
+{
+       struct ecryptfs_page_crypt_context ctx;
+       int rc;
+
+       ctx.page = page;
+       ctx.mode = ECRYPTFS_WRITEPAGE_MODE;
+       ctx.param.wbc = wbc;
+       rc = ecryptfs_encrypt_page(&ctx);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error encrypting "
+                               "page (upper index [0x%.16x])\n", page->index);
+               ClearPageUptodate(page);
+               goto out;
+       }
+       SetPageUptodate(page);
+       unlock_page(page);
+out:
+       return rc;
+}
+
+/**
+ * Reads the data from the lower file file at index lower_page_index
+ * and copies that data into page.
+ *
+ * @param page Page to fill
+ * @param lower_page_index Index of the page in the lower file to get
+ */
+int ecryptfs_do_readpage(struct file *file, struct page *page,
+                        pgoff_t lower_page_index)
+{
+       int rc;
+       struct dentry *dentry;
+       struct file *lower_file;
+       struct dentry *lower_dentry;
+       struct inode *inode;
+       struct inode *lower_inode;
+       char *page_data;
+       struct page *lower_page = NULL;
+       char *lower_page_data;
+       const struct address_space_operations *lower_a_ops;
+
+       dentry = file->f_dentry;
+       lower_file = ecryptfs_file_to_lower(file);
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       inode = dentry->d_inode;
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       lower_a_ops = lower_inode->i_mapping->a_ops;
+       lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index,
+                                    (filler_t *)lower_a_ops->readpage,
+                                    (void *)lower_file);
+       if (IS_ERR(lower_page)) {
+               rc = PTR_ERR(lower_page);
+               lower_page = NULL;
+               ecryptfs_printk(KERN_ERR, "Error reading from page cache\n");
+               goto out;
+       }
+       wait_on_page_locked(lower_page);
+       page_data = (char *)kmap(page);
+       if (!page_data) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Error mapping page\n");
+               goto out;
+       }
+       lower_page_data = (char *)kmap(lower_page);
+       if (!lower_page_data) {
+               rc = -ENOMEM;
+               ecryptfs_printk(KERN_ERR, "Error mapping page\n");
+               kunmap(page);
+               goto out;
+       }
+       memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
+       kunmap(lower_page);
+       kunmap(page);
+       rc = 0;
+out:
+       if (likely(lower_page))
+               page_cache_release(lower_page);
+       if (rc == 0)
+               SetPageUptodate(page);
+       else
+               ClearPageUptodate(page);
+       return rc;
+}
+
+/**
+ * ecryptfs_readpage
+ * @file: This is an ecryptfs file
+ * @page: ecryptfs associated page to stick the read data into
+ *
+ * Read in a page, decrypting if necessary.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+static int ecryptfs_readpage(struct file *file, struct page *page)
+{
+       int rc = 0;
+       struct ecryptfs_crypt_stat *crypt_stat;
+
+       BUG_ON(!(file && file->f_dentry && file->f_dentry->d_inode));
+       crypt_stat =
+               &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat;
+       if (!crypt_stat
+           || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)
+           || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+               ecryptfs_printk(KERN_DEBUG,
+                               "Passing through unencrypted page\n");
+               rc = ecryptfs_do_readpage(file, page, page->index);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error reading page; rc = "
+                                       "[%d]\n", rc);
+                       goto out;
+               }
+       } else {
+               rc = ecryptfs_decrypt_page(file, page);
+               if (rc) {
+
+                       ecryptfs_printk(KERN_ERR, "Error decrypting page; "
+                                       "rc = [%d]\n", rc);
+                       goto out;
+               }
+       }
+       SetPageUptodate(page);
+out:
+       if (rc)
+               ClearPageUptodate(page);
+       ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
+                       page->index);
+       unlock_page(page);
+       return rc;
+}
+
+static int fill_zeros_to_end_of_page(struct page *page, unsigned int to)
+{
+       struct inode *inode = page->mapping->host;
+       int end_byte_in_page;
+       int rc = 0;
+       char *page_virt;
+
+       if ((i_size_read(inode) / PAGE_CACHE_SIZE) == page->index) {
+               end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE;
+               if (to > end_byte_in_page)
+                       end_byte_in_page = to;
+               page_virt = kmap(page);
+               if (!page_virt) {
+                       rc = -ENOMEM;
+                       ecryptfs_printk(KERN_WARNING,
+                                       "Could not map page\n");
+                       goto out;
+               }
+               memset((page_virt + end_byte_in_page), 0,
+                      (PAGE_CACHE_SIZE - end_byte_in_page));
+               kunmap(page);
+       }
+out:
+       return rc;
+}
+
+static int ecryptfs_prepare_write(struct file *file, struct page *page,
+                                 unsigned from, unsigned to)
+{
+       int rc = 0;
+
+       kmap(page);
+       if (from == 0 && to == PAGE_CACHE_SIZE)
+               goto out;       /* If we are writing a full page, it will be
+                                  up to date. */
+       if (!PageUptodate(page))
+               rc = ecryptfs_do_readpage(file, page, page->index);
+out:
+       return rc;
+}
+
+int ecryptfs_grab_and_map_lower_page(struct page **lower_page,
+                                    char **lower_virt,
+                                    struct inode *lower_inode,
+                                    unsigned long lower_page_index)
+{
+       int rc = 0;
+
+       (*lower_page) = grab_cache_page(lower_inode->i_mapping,
+                                       lower_page_index);
+       if (!(*lower_page)) {
+               ecryptfs_printk(KERN_ERR, "grab_cache_page for "
+                               "lower_page_index = [0x%.16x] failed\n",
+                               lower_page_index);
+               rc = -EINVAL;
+               goto out;
+       }
+       if (lower_virt)
+               (*lower_virt) = kmap((*lower_page));
+       else
+               kmap((*lower_page));
+out:
+       return rc;
+}
+
+int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
+                                             struct inode *lower_inode,
+                                             struct writeback_control *wbc)
+{
+       int rc = 0;
+
+       rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); "
+                               "rc = [%d]\n", rc);
+               goto out;
+       }
+       lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+       page_cache_release(lower_page);
+out:
+       return rc;
+}
+
+static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page)
+{
+       kunmap(lower_page);
+       ecryptfs_printk(KERN_DEBUG, "Unlocking lower page with index = "
+                       "[0x%.16x]\n", lower_page->index);
+       unlock_page(lower_page);
+       page_cache_release(lower_page);
+}
+
+/**
+ * ecryptfs_write_inode_size_to_header
+ *
+ * Writes the lower file size to the first 8 bytes of the header.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+int
+ecryptfs_write_inode_size_to_header(struct file *lower_file,
+                                   struct inode *lower_inode,
+                                   struct inode *inode)
+{
+       int rc = 0;
+       struct page *header_page;
+       char *header_virt;
+       const struct address_space_operations *lower_a_ops;
+       u64 file_size;
+
+       rc = ecryptfs_grab_and_map_lower_page(&header_page, &header_virt,
+                                             lower_inode, 0);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "grab_cache_page for header page "
+                               "failed\n");
+               goto out;
+       }
+       lower_a_ops = lower_inode->i_mapping->a_ops;
+       rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
+       file_size = (u64)i_size_read(inode);
+       ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
+       file_size = cpu_to_be64(file_size);
+       memcpy(header_virt, &file_size, sizeof(u64));
+       rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8);
+       if (rc < 0)
+               ecryptfs_printk(KERN_ERR, "Error commiting header page "
+                               "write\n");
+       ecryptfs_unmap_and_release_lower_page(header_page);
+       lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+       mark_inode_dirty_sync(inode);
+out:
+       return rc;
+}
+
+int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
+                           struct file *lower_file,
+                           unsigned long lower_page_index, int byte_offset,
+                           int region_bytes)
+{
+       int rc = 0;
+
+       rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, lower_inode,
+                                             lower_page_index);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error attempting to grab and map "
+                               "lower page with index [0x%.16x]\n",
+                               lower_page_index);
+               goto out;
+       }
+       rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file,
+                                                         (*lower_page),
+                                                         byte_offset,
+                                                         region_bytes);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "prepare_write for "
+                               "lower_page_index = [0x%.16x] failed; rc = "
+                               "[%d]\n", lower_page_index, rc);
+       }
+out:
+       if (rc && (*lower_page)) {
+               ecryptfs_unmap_and_release_lower_page(*lower_page);
+               (*lower_page) = NULL;
+       }
+       return rc;
+}
+
+/**
+ * ecryptfs_commit_lower_page
+ *
+ * Returns zero on success; non-zero on error
+ */
+int
+ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
+                          struct file *lower_file, int byte_offset,
+                          int region_size)
+{
+       int rc = 0;
+
+       rc = lower_inode->i_mapping->a_ops->commit_write(
+               lower_file, lower_page, byte_offset, region_size);
+       if (rc < 0) {
+               ecryptfs_printk(KERN_ERR,
+                               "Error committing write; rc = [%d]\n", rc);
+       } else
+               rc = 0;
+       ecryptfs_unmap_and_release_lower_page(lower_page);
+       return rc;
+}
+
+/**
+ * ecryptfs_copy_page_to_lower
+ *
+ * Used for plaintext pass-through; no page index interpolation
+ * required.
+ */
+int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
+                               struct file *lower_file)
+{
+       int rc = 0;
+       struct page *lower_page;
+
+       rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file,
+                                    page->index, 0, PAGE_CACHE_SIZE);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error attempting to get page "
+                               "at index [0x%.16x]\n", page->index);
+               goto out;
+       }
+       /* TODO: aops */
+       memcpy((char *)page_address(lower_page), page_address(page),
+              PAGE_CACHE_SIZE);
+       rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file,
+                                       0, PAGE_CACHE_SIZE);
+       if (rc)
+               ecryptfs_printk(KERN_ERR, "Error attempting to commit page "
+                               "at index [0x%.16x]\n", page->index);
+out:
+       return rc;
+}
+
+static int
+process_new_file(struct ecryptfs_crypt_stat *crypt_stat,
+                struct file *file, struct inode *inode)
+{
+       struct page *header_page;
+       const struct address_space_operations *lower_a_ops;
+       struct inode *lower_inode;
+       struct file *lower_file;
+       char *header_virt;
+       int rc = 0;
+       int current_header_page = 0;
+       int header_pages;
+       int more_header_data_to_be_written = 1;
+
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       lower_file = ecryptfs_file_to_lower(file);
+       lower_a_ops = lower_inode->i_mapping->a_ops;
+       header_pages = ((crypt_stat->header_extent_size
+                        * crypt_stat->num_header_extents_at_front)
+                       / PAGE_CACHE_SIZE);
+       BUG_ON(header_pages < 1);
+       while (current_header_page < header_pages) {
+               rc = ecryptfs_grab_and_map_lower_page(&header_page,
+                                                     &header_virt,
+                                                     lower_inode,
+                                                     current_header_page);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "grab_cache_page for "
+                                       "header page [%d] failed; rc = [%d]\n",
+                                       current_header_page, rc);
+                       goto out;
+               }
+               rc = lower_a_ops->prepare_write(lower_file, header_page, 0,
+                                               PAGE_CACHE_SIZE);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error preparing to write "
+                                       "header page out; rc = [%d]\n", rc);
+                       goto out;
+               }
+               memset(header_virt, 0, PAGE_CACHE_SIZE);
+               if (more_header_data_to_be_written) {
+                       rc = ecryptfs_write_headers_virt(header_virt,
+                                                        crypt_stat,
+                                                        file->f_dentry);
+                       if (rc) {
+                               ecryptfs_printk(KERN_WARNING, "Error "
+                                               "generating header; rc = "
+                                               "[%d]\n", rc);
+                               rc = -EIO;
+                               memset(header_virt, 0, PAGE_CACHE_SIZE);
+                               ecryptfs_unmap_and_release_lower_page(
+                                       header_page);
+                               goto out;
+                       }
+                       if (current_header_page == 0)
+                               memset(header_virt, 0, 8);
+                       more_header_data_to_be_written = 0;
+               }
+               rc = lower_a_ops->commit_write(lower_file, header_page, 0,
+                                              PAGE_CACHE_SIZE);
+               ecryptfs_unmap_and_release_lower_page(header_page);
+               if (rc < 0) {
+                       ecryptfs_printk(KERN_ERR,
+                                       "Error commiting header page write; "
+                                       "rc = [%d]\n", rc);
+                       break;
+               }
+               current_header_page++;
+       }
+       if (rc >= 0) {
+               rc = 0;
+               ecryptfs_printk(KERN_DEBUG, "lower_inode->i_blocks = "
+                               "[0x%.16x]\n", lower_inode->i_blocks);
+               i_size_write(inode, 0);
+               lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+               mark_inode_dirty_sync(inode);
+       }
+       ecryptfs_printk(KERN_DEBUG, "Clearing ECRYPTFS_NEW_FILE flag in "
+                       "crypt_stat at memory location [%p]\n", crypt_stat);
+       ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE);
+out:
+       return rc;
+}
+
+/**
+ * ecryptfs_commit_write
+ * @file: The eCryptfs file object
+ * @page: The eCryptfs page
+ * @from: Ignored (we rotate the page IV on each write)
+ * @to: Ignored
+ *
+ * This is where we encrypt the data and pass the encrypted data to
+ * the lower filesystem.  In OpenPGP-compatible mode, we operate on
+ * entire underlying packets.
+ */
+static int ecryptfs_commit_write(struct file *file, struct page *page,
+                                unsigned from, unsigned to)
+{
+       struct ecryptfs_page_crypt_context ctx;
+       loff_t pos;
+       struct inode *inode;
+       struct inode *lower_inode;
+       struct file *lower_file;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       int rc;
+
+       inode = page->mapping->host;
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       lower_file = ecryptfs_file_to_lower(file);
+       mutex_lock(&lower_inode->i_mutex);
+       crypt_stat =
+               &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat;
+       if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) {
+               ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
+                       "crypt_stat at memory location [%p]\n", crypt_stat);
+               rc = process_new_file(crypt_stat, file, inode);
+               if (rc) {
+                       ecryptfs_printk(KERN_ERR, "Error processing new "
+                                       "file; rc = [%d]\n", rc);
+                       goto out;
+               }
+       } else
+               ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
+       ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
+                       "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
+                       to);
+       rc = fill_zeros_to_end_of_page(page, to);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
+                               "zeros in page with index = [0x%.16x]\n",
+                               page->index);
+               goto out;
+       }
+       ctx.page = page;
+       ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE;
+       ctx.param.lower_file = lower_file;
+       rc = ecryptfs_encrypt_page(&ctx);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
+                               "index [0x%.16x])\n", page->index);
+               goto out;
+       }
+       rc = 0;
+       inode->i_blocks = lower_inode->i_blocks;
+       pos = (page->index << PAGE_CACHE_SHIFT) + to;
+       if (pos > i_size_read(inode)) {
+               i_size_write(inode, pos);
+               ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
+                               "[0x%.16x]\n", i_size_read(inode));
+       }
+       ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode);
+       lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
+       mark_inode_dirty_sync(inode);
+out:
+       kunmap(page); /* mapped in prior call (prepare_write) */
+       if (rc < 0)
+               ClearPageUptodate(page);
+       else
+               SetPageUptodate(page);
+       mutex_unlock(&lower_inode->i_mutex);
+       return rc;
+}
+
+/**
+ * write_zeros
+ * @file: The ecryptfs file
+ * @index: The index in which we are writing
+ * @start: The position after the last block of data
+ * @num_zeros: The number of zeros to write
+ *
+ * Write a specified number of zero's to a page.
+ *
+ * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE
+ */
+static
+int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
+{
+       int rc = 0;
+       struct page *tmp_page;
+
+       tmp_page = ecryptfs_get1page(file, index);
+       if (IS_ERR(tmp_page)) {
+               ecryptfs_printk(KERN_ERR, "Error getting page at index "
+                               "[0x%.16x]\n", index);
+               rc = PTR_ERR(tmp_page);
+               goto out;
+       }
+       kmap(tmp_page);
+       rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros);
+       if (rc) {
+               ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
+                               "to remainder of page at index [0x%.16x]\n",
+                               index);
+               kunmap(tmp_page);
+               page_cache_release(tmp_page);
+               goto out;
+       }
+       memset(((char *)page_address(tmp_page) + start), 0, num_zeros);
+       rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros);
+       if (rc < 0) {
+               ecryptfs_printk(KERN_ERR, "Error attempting to write zero's "
+                               "to remainder of page at index [0x%.16x]\n",
+                               index);
+               kunmap(tmp_page);
+               page_cache_release(tmp_page);
+               goto out;
+       }
+       rc = 0;
+       kunmap(tmp_page);
+       page_cache_release(tmp_page);
+out:
+       return rc;
+}
+
+static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
+{
+       int rc = 0;
+       struct inode *inode;
+       struct inode *lower_inode;
+
+       inode = (struct inode *)mapping->host;
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       if (lower_inode->i_mapping->a_ops->bmap)
+               rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping,
+                                                        block);
+       return rc;
+}
+
+static void ecryptfs_sync_page(struct page *page)
+{
+       struct inode *inode;
+       struct inode *lower_inode;
+       struct page *lower_page;
+
+       inode = page->mapping->host;
+       lower_inode = ecryptfs_inode_to_lower(inode);
+       /* NOTE: Recently swapped with grab_cache_page(), since
+        * sync_page() just makes sure that pending I/O gets done. */
+       lower_page = find_lock_page(lower_inode->i_mapping, page->index);
+       if (!lower_page) {
+               ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
+               return;
+       }
+       lower_page->mapping->a_ops->sync_page(lower_page);
+       ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
+                       lower_page->index);
+       unlock_page(lower_page);
+       page_cache_release(lower_page);
+}
+
+struct address_space_operations ecryptfs_aops = {
+       .writepage = ecryptfs_writepage,
+       .readpage = ecryptfs_readpage,
+       .prepare_write = ecryptfs_prepare_write,
+       .commit_write = ecryptfs_commit_write,
+       .bmap = ecryptfs_bmap,
+       .sync_page = ecryptfs_sync_page,
+};
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
new file mode 100644 (file)
index 0000000..c337c04
--- /dev/null
@@ -0,0 +1,198 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 1997-2003 Erez Zadok
+ * Copyright (C) 2001-2003 Stony Brook University
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *              Michael C. Thompson <mcthomps@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/key.h>
+#include <linux/seq_file.h>
+#include <linux/crypto.h>
+#include "ecryptfs_kernel.h"
+
+struct kmem_cache *ecryptfs_inode_info_cache;
+
+/**
+ * ecryptfs_alloc_inode - allocate an ecryptfs inode
+ * @sb: Pointer to the ecryptfs super block
+ *
+ * Called to bring an inode into existence.
+ *
+ * Only handle allocation, setting up structures should be done in
+ * ecryptfs_read_inode. This is because the kernel, between now and
+ * then, will 0 out the private data pointer.
+ *
+ * Returns a pointer to a newly allocated inode, NULL otherwise
+ */
+static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
+{
+       struct ecryptfs_inode_info *ecryptfs_inode;
+       struct inode *inode = NULL;
+
+       ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache,
+                                         SLAB_KERNEL);
+       if (unlikely(!ecryptfs_inode))
+               goto out;
+       ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat);
+       inode = &ecryptfs_inode->vfs_inode;
+out:
+       return inode;
+}
+
+/**
+ * ecryptfs_destroy_inode
+ * @inode: The ecryptfs inode
+ *
+ * This is used during the final destruction of the inode.
+ * All allocation of memory related to the inode, including allocated
+ * memory in the crypt_stat struct, will be released here.
+ * There should be no chance that this deallocation will be missed.
+ */
+static void ecryptfs_destroy_inode(struct inode *inode)
+{
+       struct ecryptfs_inode_info *inode_info;
+
+       inode_info = ecryptfs_inode_to_private(inode);
+       ecryptfs_destruct_crypt_stat(&inode_info->crypt_stat);
+       kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
+}
+
+/**
+ * ecryptfs_init_inode
+ * @inode: The ecryptfs inode
+ *
+ * Set up the ecryptfs inode.
+ */
+void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode)
+{
+       ecryptfs_set_inode_lower(inode, lower_inode);
+       inode->i_ino = lower_inode->i_ino;
+       inode->i_version++;
+       inode->i_op = &ecryptfs_main_iops;
+       inode->i_fop = &ecryptfs_main_fops;
+       inode->i_mapping->a_ops = &ecryptfs_aops;
+}
+
+/**
+ * ecryptfs_put_super
+ * @sb: Pointer to the ecryptfs super block
+ *
+ * Final actions when unmounting a file system.
+ * This will handle deallocation and release of our private data.
+ */
+static void ecryptfs_put_super(struct super_block *sb)
+{
+       struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
+
+       ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat);
+       kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
+       ecryptfs_set_superblock_private(sb, NULL);
+}
+
+/**
+ * ecryptfs_statfs
+ * @sb: The ecryptfs super block
+ * @buf: The struct kstatfs to fill in with stats
+ *
+ * Get the filesystem statistics. Currently, we let this pass right through
+ * to the lower filesystem and take no action ourselves.
+ */
+static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+       return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf);
+}
+
+/**
+ * ecryptfs_clear_inode
+ * @inode - The ecryptfs inode
+ *
+ * Called by iput() when the inode reference count reached zero
+ * and the inode is not hashed anywhere.  Used to clear anything
+ * that needs to be, before the inode is completely destroyed and put
+ * on the inode free list. We use this to drop out reference to the
+ * lower inode.
+ */
+static void ecryptfs_clear_inode(struct inode *inode)
+{
+       iput(ecryptfs_inode_to_lower(inode));
+}
+
+/**
+ * ecryptfs_umount_begin
+ *
+ * Called in do_umount().
+ */
+static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags)
+{
+       struct vfsmount *lower_mnt =
+               ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root);
+       struct super_block *lower_sb;
+
+       mntput(lower_mnt);
+       lower_sb = lower_mnt->mnt_sb;
+       if (lower_sb->s_op->umount_begin)
+               lower_sb->s_op->umount_begin(lower_mnt, flags);
+}
+
+/**
+ * ecryptfs_show_options
+ *
+ * Prints the directory we are currently mounted over.
+ * Returns zero on success; non-zero otherwise
+ */
+static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+       struct super_block *sb = mnt->mnt_sb;
+       struct dentry *lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root);
+       struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(sb->s_root);
+       char *tmp_page;
+       char *path;
+       int rc = 0;
+
+       tmp_page = (char *)__get_free_page(GFP_KERNEL);
+       if (!tmp_page) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       path = d_path(lower_root_dentry, lower_mnt, tmp_page, PAGE_SIZE);
+       if (IS_ERR(path)) {
+               rc = PTR_ERR(path);
+               goto out;
+       }
+       seq_printf(m, ",dir=%s", path);
+       free_page((unsigned long)tmp_page);
+out:
+       return rc;
+}
+
+struct super_operations ecryptfs_sops = {
+       .alloc_inode = ecryptfs_alloc_inode,
+       .destroy_inode = ecryptfs_destroy_inode,
+       .drop_inode = generic_delete_inode,
+       .put_super = ecryptfs_put_super,
+       .statfs = ecryptfs_statfs,
+       .remount_fs = NULL,
+       .clear_inode = ecryptfs_clear_inode,
+       .umount_begin = ecryptfs_umount_begin,
+       .show_options = ecryptfs_show_options
+};
index ae783066fc3aed8492a729b61bb17eb0d623b52e..1528a6fd02992f1858ee254fe01039520da77bd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/hfs/part_tbl.c
+ * linux/fs/hfsplus/part_tbl.c
  *
  * Copyright (C) 1996-1997  Paul H. Hargrove
  * This file may be distributed under the terms of the GNU General Public License.
index 32a8caf0c41ebf44e170feb78cf4c2ae19ba0eb5..10be51290a27e887c7cc503dbbb21ef4cc82301e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/commit.c
+ * linux/fs/jbd/commit.c
  *
  * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
  *
index 7af6099c911c2cbb584932f822788b5e92ab4d9f..c518dd8fe60a5c539055b33e7e6b33860daad361 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/journal.c
+ * linux/fs/jbd/journal.c
  *
  * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
  *
index 87e1d03e82673cdf14b435025556f608f07b68ec..e8c7765419e8c8e55e0f8a9d3a6706c149fcabba 100644 (file)
@@ -143,43 +143,13 @@ u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock)
  * server crash.
  */
 
-/*
- * Someone has sent us an SM_NOTIFY. Ensure we bind to the new port number,
- * that we mark locks for reclaiming, and that we bump the pseudo NSM state.
- */
-static void nlmclnt_prepare_reclaim(struct nlm_host *host)
-{
-       down_write(&host->h_rwsem);
-       host->h_monitored = 0;
-       host->h_state++;
-       host->h_nextrebind = 0;
-       nlm_rebind_host(host);
-
-       /*
-        * Mark the locks for reclaiming.
-        */
-       list_splice_init(&host->h_granted, &host->h_reclaim);
-
-       dprintk("NLM: reclaiming locks for host %s\n", host->h_name);
-}
-
-static void nlmclnt_finish_reclaim(struct nlm_host *host)
-{
-       host->h_reclaiming = 0;
-       up_write(&host->h_rwsem);
-       dprintk("NLM: done reclaiming locks for host %s", host->h_name);
-}
-
 /*
  * Reclaim all locks on server host. We do this by spawning a separate
  * reclaimer thread.
  */
 void
-nlmclnt_recovery(struct nlm_host *host, u32 newstate)
+nlmclnt_recovery(struct nlm_host *host)
 {
-       if (host->h_nsmstate == newstate)
-               return;
-       host->h_nsmstate = newstate;
        if (!host->h_reclaiming++) {
                nlm_get_host(host);
                __module_get(THIS_MODULE);
@@ -199,18 +169,30 @@ reclaimer(void *ptr)
        daemonize("%s-reclaim", host->h_name);
        allow_signal(SIGKILL);
 
+       down_write(&host->h_rwsem);
+
        /* This one ensures that our parent doesn't terminate while the
         * reclaim is in progress */
        lock_kernel();
        lockd_up(0); /* note: this cannot fail as lockd is already running */
 
-       nlmclnt_prepare_reclaim(host);
-       /* First, reclaim all locks that have been marked. */
+       dprintk("lockd: reclaiming locks for host %s", host->h_name);
+
 restart:
        nsmstate = host->h_nsmstate;
+
+       /* Force a portmap getport - the peer's lockd will
+        * most likely end up on a different port.
+        */
+       host->h_nextrebind = jiffies;
+       nlm_rebind_host(host);
+
+       /* First, reclaim all locks that have been granted. */
+       list_splice_init(&host->h_granted, &host->h_reclaim);
        list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) {
                list_del_init(&fl->fl_u.nfs_fl.list);
 
+               /* Why are we leaking memory here? --okir */
                if (signalled())
                        continue;
                if (nlmclnt_reclaim(host, fl) != 0)
@@ -218,11 +200,13 @@ restart:
                list_add_tail(&fl->fl_u.nfs_fl.list, &host->h_granted);
                if (host->h_nsmstate != nsmstate) {
                        /* Argh! The server rebooted again! */
-                       list_splice_init(&host->h_granted, &host->h_reclaim);
                        goto restart;
                }
        }
-       nlmclnt_finish_reclaim(host);
+
+       host->h_reclaiming = 0;
+       up_write(&host->h_rwsem);
+       dprintk("NLM: done reclaiming locks for host %s", host->h_name);
 
        /* Now, wake up all processes that sleep on a blocked lock */
        list_for_each_entry(block, &nlm_blocked, b_list) {
index 0116729cec5f717ed246715e813108e7b12cb6b7..3d84f600b633693f37078a28ee9fb5e31290b378 100644 (file)
@@ -36,14 +36,14 @@ static const struct rpc_call_ops nlmclnt_cancel_ops;
 /*
  * Cookie counter for NLM requests
  */
-static u32     nlm_cookie = 0x1234;
+static atomic_t        nlm_cookie = ATOMIC_INIT(0x1234);
 
-static inline void nlmclnt_next_cookie(struct nlm_cookie *c)
+void nlmclnt_next_cookie(struct nlm_cookie *c)
 {
-       memcpy(c->data, &nlm_cookie, 4);
-       memset(c->data+4, 0, 4);
+       u32     cookie = atomic_inc_return(&nlm_cookie);
+
+       memcpy(c->data, &cookie, 4);
        c->len=4;
-       nlm_cookie++;
 }
 
 static struct nlm_lockowner *nlm_get_lockowner(struct nlm_lockowner *lockowner)
@@ -153,6 +153,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
 {
        struct rpc_clnt         *client = NFS_CLIENT(inode);
        struct sockaddr_in      addr;
+       struct nfs_server       *nfssrv = NFS_SERVER(inode);
        struct nlm_host         *host;
        struct nlm_rqst         *call;
        sigset_t                oldset;
@@ -166,7 +167,9 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
        }
 
        rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
-       host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers);
+       host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers,
+                                  nfssrv->nfs_client->cl_hostname,
+                                  strlen(nfssrv->nfs_client->cl_hostname));
        if (host == NULL)
                return -ENOLCK;
 
@@ -499,7 +502,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
        unsigned char fl_flags = fl->fl_flags;
        int status = -ENOLCK;
 
-       if (!host->h_monitored && nsm_monitor(host) < 0) {
+       if (nsm_monitor(host) < 0) {
                printk(KERN_NOTICE "lockd: failed to monitor %s\n",
                                        host->h_name);
                goto out;
index a0d0b58ce7a49968aa8ed942d00fbec3e9fc9539..fb24a97303458f1b282f81111895c105e2c0399f 100644 (file)
 #define NLM_HOST_EXPIRE                ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ)
 #define NLM_HOST_COLLECT       ((nrhosts > NLM_HOST_MAX)? 120 * HZ :  60 * HZ)
 
-static struct nlm_host *       nlm_hosts[NLM_HOST_NRHASH];
+static struct hlist_head       nlm_hosts[NLM_HOST_NRHASH];
 static unsigned long           next_gc;
 static int                     nrhosts;
 static DEFINE_MUTEX(nlm_host_mutex);
 
 
 static void                    nlm_gc_hosts(void);
+static struct nsm_handle *     __nsm_find(const struct sockaddr_in *,
+                                       const char *, int, int);
 
 /*
  * Find an NLM server handle in the cache. If there is none, create it.
  */
 struct nlm_host *
-nlmclnt_lookup_host(struct sockaddr_in *sin, int proto, int version)
+nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version,
+                       const char *hostname, int hostname_len)
 {
-       return nlm_lookup_host(0, sin, proto, version);
+       return nlm_lookup_host(0, sin, proto, version,
+                              hostname, hostname_len);
 }
 
 /*
  * Find an NLM client handle in the cache. If there is none, create it.
  */
 struct nlm_host *
-nlmsvc_lookup_host(struct svc_rqst *rqstp)
+nlmsvc_lookup_host(struct svc_rqst *rqstp,
+                       const char *hostname, int hostname_len)
 {
        return nlm_lookup_host(1, &rqstp->rq_addr,
-                              rqstp->rq_prot, rqstp->rq_vers);
+                              rqstp->rq_prot, rqstp->rq_vers,
+                              hostname, hostname_len);
 }
 
 /*
  * Common host lookup routine for server & client
  */
 struct nlm_host *
-nlm_lookup_host(int server, struct sockaddr_in *sin,
-                                       int proto, int version)
+nlm_lookup_host(int server, const struct sockaddr_in *sin,
+                                       int proto, int version,
+                                       const char *hostname,
+                                       int hostname_len)
 {
-       struct nlm_host *host, **hp;
-       u32             addr;
+       struct hlist_head *chain;
+       struct hlist_node *pos;
+       struct nlm_host *host;
+       struct nsm_handle *nsm = NULL;
        int             hash;
 
-       dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n",
-                       (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version);
+       dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n",
+                       NIPQUAD(sin->sin_addr.s_addr), proto, version,
+                       server? "server" : "client",
+                       hostname_len,
+                       hostname? hostname : "<none>");
+
 
        hash = NLM_ADDRHASH(sin->sin_addr.s_addr);
 
@@ -76,7 +90,22 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
        if (time_after_eq(jiffies, next_gc))
                nlm_gc_hosts();
 
-       for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
+       /* We may keep several nlm_host objects for a peer, because each
+        * nlm_host is identified by
+        * (address, protocol, version, server/client)
+        * We could probably simplify this a little by putting all those
+        * different NLM rpc_clients into one single nlm_host object.
+        * This would allow us to have one nlm_host per address.
+        */
+       chain = &nlm_hosts[hash];
+       hlist_for_each_entry(host, pos, chain, h_hash) {
+               if (!nlm_cmp_addr(&host->h_addr, sin))
+                       continue;
+
+               /* See if we have an NSM handle for this client */
+               if (!nsm)
+                       nsm = host->h_nsmhandle;
+
                if (host->h_proto != proto)
                        continue;
                if (host->h_version != version)
@@ -84,28 +113,30 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
                if (host->h_server != server)
                        continue;
 
-               if (nlm_cmp_addr(&host->h_addr, sin)) {
-                       if (hp != nlm_hosts + hash) {
-                               *hp = host->h_next;
-                               host->h_next = nlm_hosts[hash];
-                               nlm_hosts[hash] = host;
-                       }
-                       nlm_get_host(host);
-                       mutex_unlock(&nlm_host_mutex);
-                       return host;
-               }
-       }
+               /* Move to head of hash chain. */
+               hlist_del(&host->h_hash);
+               hlist_add_head(&host->h_hash, chain);
 
-       /* Ooops, no host found, create it */
-       dprintk("lockd: creating host entry\n");
+               nlm_get_host(host);
+               goto out;
+       }
+       if (nsm)
+               atomic_inc(&nsm->sm_count);
 
-       host = kzalloc(sizeof(*host), GFP_KERNEL);
-       if (!host)
-               goto nohost;
+       host = NULL;
 
-       addr = sin->sin_addr.s_addr;
-       sprintf(host->h_name, "%u.%u.%u.%u", NIPQUAD(addr));
+       /* Sadly, the host isn't in our hash table yet. See if
+        * we have an NSM handle for it. If not, create one.
+        */
+       if (!nsm && !(nsm = nsm_find(sin, hostname, hostname_len)))
+               goto out;
 
+       host = kzalloc(sizeof(*host), GFP_KERNEL);
+       if (!host) {
+               nsm_release(nsm);
+               goto out;
+       }
+       host->h_name       = nsm->sm_name;
        host->h_addr       = *sin;
        host->h_addr.sin_port = 0;      /* ouch! */
        host->h_version    = version;
@@ -119,9 +150,9 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
        init_rwsem(&host->h_rwsem);
        host->h_state      = 0;                 /* pseudo NSM state */
        host->h_nsmstate   = 0;                 /* real NSM state */
+       host->h_nsmhandle  = nsm;
        host->h_server     = server;
-       host->h_next       = nlm_hosts[hash];
-       nlm_hosts[hash]    = host;
+       hlist_add_head(&host->h_hash, chain);
        INIT_LIST_HEAD(&host->h_lockowners);
        spin_lock_init(&host->h_lock);
        INIT_LIST_HEAD(&host->h_granted);
@@ -130,35 +161,39 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
        if (++nrhosts > NLM_HOST_MAX)
                next_gc = 0;
 
-nohost:
+out:
        mutex_unlock(&nlm_host_mutex);
        return host;
 }
 
-struct nlm_host *
-nlm_find_client(void)
+/*
+ * Destroy a host
+ */
+static void
+nlm_destroy_host(struct nlm_host *host)
 {
-       /* find a nlm_host for a client for which h_killed == 0.
-        * and return it
+       struct rpc_clnt *clnt;
+
+       BUG_ON(!list_empty(&host->h_lockowners));
+       BUG_ON(atomic_read(&host->h_count));
+
+       /*
+        * Release NSM handle and unmonitor host.
         */
-       int hash;
-       mutex_lock(&nlm_host_mutex);
-       for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) {
-               struct nlm_host *host, **hp;
-               for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
-                       if (host->h_server &&
-                           host->h_killed == 0) {
-                               nlm_get_host(host);
-                               mutex_unlock(&nlm_host_mutex);
-                               return host;
-                       }
+       nsm_unmonitor(host);
+
+       if ((clnt = host->h_rpcclnt) != NULL) {
+               if (atomic_read(&clnt->cl_users)) {
+                       printk(KERN_WARNING
+                               "lockd: active RPC handle\n");
+                       clnt->cl_dead = 1;
+               } else {
+                       rpc_destroy_client(host->h_rpcclnt);
                }
        }
-       mutex_unlock(&nlm_host_mutex);
-       return NULL;
+       kfree(host);
 }
 
-                               
 /*
  * Create the NLM RPC client for an NLM peer
  */
@@ -259,6 +294,65 @@ void nlm_release_host(struct nlm_host *host)
        }
 }
 
+/*
+ * We were notified that the host indicated by address &sin
+ * has rebooted.
+ * Release all resources held by that peer.
+ */
+void nlm_host_rebooted(const struct sockaddr_in *sin,
+                               const char *hostname, int hostname_len,
+                               u32 new_state)
+{
+       struct hlist_head *chain;
+       struct hlist_node *pos;
+       struct nsm_handle *nsm;
+       struct nlm_host *host;
+
+       dprintk("lockd: nlm_host_rebooted(%s, %u.%u.%u.%u)\n",
+                       hostname, NIPQUAD(sin->sin_addr));
+
+       /* Find the NSM handle for this peer */
+       if (!(nsm = __nsm_find(sin, hostname, hostname_len, 0)))
+               return;
+
+       /* When reclaiming locks on this peer, make sure that
+        * we set up a new notification */
+       nsm->sm_monitored = 0;
+
+       /* Mark all hosts tied to this NSM state as having rebooted.
+        * We run the loop repeatedly, because we drop the host table
+        * lock for this.
+        * To avoid processing a host several times, we match the nsmstate.
+        */
+again: mutex_lock(&nlm_host_mutex);
+       for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+               hlist_for_each_entry(host, pos, chain, h_hash) {
+                       if (host->h_nsmhandle == nsm
+                        && host->h_nsmstate != new_state) {
+                               host->h_nsmstate = new_state;
+                               host->h_state++;
+
+                               nlm_get_host(host);
+                               mutex_unlock(&nlm_host_mutex);
+
+                               if (host->h_server) {
+                                       /* We're server for this guy, just ditch
+                                        * all the locks he held. */
+                                       nlmsvc_free_host_resources(host);
+                               } else {
+                                       /* He's the server, initiate lock recovery. */
+                                       nlmclnt_recovery(host);
+                               }
+
+                               nlm_release_host(host);
+                               goto again;
+                       }
+               }
+       }
+
+       mutex_unlock(&nlm_host_mutex);
+}
+
 /*
  * Shut down the hosts module.
  * Note that this routine is called only at server shutdown time.
@@ -266,16 +360,17 @@ void nlm_release_host(struct nlm_host *host)
 void
 nlm_shutdown_hosts(void)
 {
+       struct hlist_head *chain;
+       struct hlist_node *pos;
        struct nlm_host *host;
-       int             i;
 
        dprintk("lockd: shutting down host module\n");
        mutex_lock(&nlm_host_mutex);
 
        /* First, make all hosts eligible for gc */
        dprintk("lockd: nuking all hosts...\n");
-       for (i = 0; i < NLM_HOST_NRHASH; i++) {
-               for (host = nlm_hosts[i]; host; host = host->h_next)
+       for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+               hlist_for_each_entry(host, pos, chain, h_hash)
                        host->h_expires = jiffies - 1;
        }
 
@@ -287,8 +382,8 @@ nlm_shutdown_hosts(void)
        if (nrhosts) {
                printk(KERN_WARNING "lockd: couldn't shutdown host module!\n");
                dprintk("lockd: %d hosts left:\n", nrhosts);
-               for (i = 0; i < NLM_HOST_NRHASH; i++) {
-                       for (host = nlm_hosts[i]; host; host = host->h_next) {
+               for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+                       hlist_for_each_entry(host, pos, chain, h_hash) {
                                dprintk("       %s (cnt %d use %d exp %ld)\n",
                                        host->h_name, atomic_read(&host->h_count),
                                        host->h_inuse, host->h_expires);
@@ -305,45 +400,32 @@ nlm_shutdown_hosts(void)
 static void
 nlm_gc_hosts(void)
 {
-       struct nlm_host **q, *host;
-       struct rpc_clnt *clnt;
-       int             i;
+       struct hlist_head *chain;
+       struct hlist_node *pos, *next;
+       struct nlm_host *host;
 
        dprintk("lockd: host garbage collection\n");
-       for (i = 0; i < NLM_HOST_NRHASH; i++) {
-               for (host = nlm_hosts[i]; host; host = host->h_next)
+       for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+               hlist_for_each_entry(host, pos, chain, h_hash)
                        host->h_inuse = 0;
        }
 
        /* Mark all hosts that hold locks, blocks or shares */
        nlmsvc_mark_resources();
 
-       for (i = 0; i < NLM_HOST_NRHASH; i++) {
-               q = &nlm_hosts[i];
-               while ((host = *q) != NULL) {
+       for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
+               hlist_for_each_entry_safe(host, pos, next, chain, h_hash) {
                        if (atomic_read(&host->h_count) || host->h_inuse
                         || time_before(jiffies, host->h_expires)) {
                                dprintk("nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)\n",
                                        host->h_name, atomic_read(&host->h_count),
                                        host->h_inuse, host->h_expires);
-                               q = &host->h_next;
                                continue;
                        }
                        dprintk("lockd: delete host %s\n", host->h_name);
-                       *q = host->h_next;
-                       /* Don't unmonitor hosts that have been invalidated */
-                       if (host->h_monitored && !host->h_killed)
-                               nsm_unmonitor(host);
-                       if ((clnt = host->h_rpcclnt) != NULL) {
-                               if (atomic_read(&clnt->cl_users)) {
-                                       printk(KERN_WARNING
-                                               "lockd: active RPC handle\n");
-                                       clnt->cl_dead = 1;
-                               } else {
-                                       rpc_destroy_client(host->h_rpcclnt);
-                               }
-                       }
-                       kfree(host);
+                       hlist_del_init(&host->h_hash);
+
+                       nlm_destroy_host(host);
                        nrhosts--;
                }
        }
@@ -351,3 +433,88 @@ nlm_gc_hosts(void)
        next_gc = jiffies + NLM_HOST_COLLECT;
 }
 
+
+/*
+ * Manage NSM handles
+ */
+static LIST_HEAD(nsm_handles);
+static DEFINE_MUTEX(nsm_mutex);
+
+static struct nsm_handle *
+__nsm_find(const struct sockaddr_in *sin,
+               const char *hostname, int hostname_len,
+               int create)
+{
+       struct nsm_handle *nsm = NULL;
+       struct list_head *pos;
+
+       if (!sin)
+               return NULL;
+
+       if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
+               if (printk_ratelimit()) {
+                       printk(KERN_WARNING "Invalid hostname \"%.*s\" "
+                                           "in NFS lock request\n",
+                               hostname_len, hostname);
+               }
+               return NULL;
+       }
+
+       mutex_lock(&nsm_mutex);
+       list_for_each(pos, &nsm_handles) {
+               nsm = list_entry(pos, struct nsm_handle, sm_link);
+
+               if (hostname && nsm_use_hostnames) {
+                       if (strlen(nsm->sm_name) != hostname_len
+                        || memcmp(nsm->sm_name, hostname, hostname_len))
+                               continue;
+               } else if (!nlm_cmp_addr(&nsm->sm_addr, sin))
+                       continue;
+               atomic_inc(&nsm->sm_count);
+               goto out;
+       }
+
+       if (!create) {
+               nsm = NULL;
+               goto out;
+       }
+
+       nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
+       if (nsm != NULL) {
+               nsm->sm_addr = *sin;
+               nsm->sm_name = (char *) (nsm + 1);
+               memcpy(nsm->sm_name, hostname, hostname_len);
+               nsm->sm_name[hostname_len] = '\0';
+               atomic_set(&nsm->sm_count, 1);
+
+               list_add(&nsm->sm_link, &nsm_handles);
+       }
+
+out:
+       mutex_unlock(&nsm_mutex);
+       return nsm;
+}
+
+struct nsm_handle *
+nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len)
+{
+       return __nsm_find(sin, hostname, hostname_len, 1);
+}
+
+/*
+ * Release an NSM handle
+ */
+void
+nsm_release(struct nsm_handle *nsm)
+{
+       if (!nsm)
+               return;
+       if (atomic_dec_and_test(&nsm->sm_count)) {
+               mutex_lock(&nsm_mutex);
+               if (atomic_read(&nsm->sm_count) == 0) {
+                       list_del(&nsm->sm_link);
+                       kfree(nsm);
+               }
+               mutex_unlock(&nsm_mutex);
+       }
+}
index a816b920d431fcfd60fc806b10bd4e0cc25c02f7..e0179f8c327f65657ffb6b83e03fa88265dce0c5 100644 (file)
@@ -24,13 +24,13 @@ static struct rpc_program   nsm_program;
 /*
  * Local NSM state
  */
-u32                            nsm_local_state;
+int                            nsm_local_state;
 
 /*
  * Common procedure for SM_MON/SM_UNMON calls
  */
 static int
-nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
+nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 {
        struct rpc_clnt *clnt;
        int             status;
@@ -46,10 +46,11 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
                goto out;
        }
 
-       args.addr = host->h_addr.sin_addr.s_addr;
-       args.proto= (host->h_proto<<1) | host->h_server;
+       memset(&args, 0, sizeof(args));
+       args.mon_name = nsm->sm_name;
+       args.addr = nsm->sm_addr.sin_addr.s_addr;
        args.prog = NLM_PROGRAM;
-       args.vers = host->h_version;
+       args.vers = 3;
        args.proc = NLMPROC_NSM_NOTIFY;
        memset(res, 0, sizeof(*res));
 
@@ -70,17 +71,22 @@ nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res)
 int
 nsm_monitor(struct nlm_host *host)
 {
+       struct nsm_handle *nsm = host->h_nsmhandle;
        struct nsm_res  res;
        int             status;
 
        dprintk("lockd: nsm_monitor(%s)\n", host->h_name);
+       BUG_ON(nsm == NULL);
 
-       status = nsm_mon_unmon(host, SM_MON, &res);
+       if (nsm->sm_monitored)
+               return 0;
+
+       status = nsm_mon_unmon(nsm, SM_MON, &res);
 
        if (status < 0 || res.status != 0)
                printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name);
        else
-               host->h_monitored = 1;
+               nsm->sm_monitored = 1;
        return status;
 }
 
@@ -90,16 +96,26 @@ nsm_monitor(struct nlm_host *host)
 int
 nsm_unmonitor(struct nlm_host *host)
 {
+       struct nsm_handle *nsm = host->h_nsmhandle;
        struct nsm_res  res;
-       int             status;
-
-       dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
-
-       status = nsm_mon_unmon(host, SM_UNMON, &res);
-       if (status < 0)
-               printk(KERN_NOTICE "lockd: cannot unmonitor %s\n", host->h_name);
-       else
-               host->h_monitored = 0;
+       int             status = 0;
+
+       if (nsm == NULL)
+               return 0;
+       host->h_nsmhandle = NULL;
+
+       if (atomic_read(&nsm->sm_count) == 1
+        && nsm->sm_monitored && !nsm->sm_sticky) {
+               dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
+
+               status = nsm_mon_unmon(nsm, SM_UNMON, &res);
+               if (status < 0)
+                       printk(KERN_NOTICE "lockd: cannot unmonitor %s\n",
+                                       host->h_name);
+               else
+                       nsm->sm_monitored = 0;
+       }
+       nsm_release(nsm);
        return status;
 }
 
@@ -135,7 +151,7 @@ nsm_create(void)
 static u32 *
 xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 {
-       char    buffer[20];
+       char    buffer[20], *name;
 
        /*
         * Use the dotted-quad IP address of the remote host as
@@ -143,8 +159,13 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
         * hostname first for whatever remote hostname it receives,
         * so this works alright.
         */
-       sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
-       if (!(p = xdr_encode_string(p, buffer))
+       if (nsm_use_hostnames) {
+               name = argp->mon_name;
+       } else {
+               sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
+               name = buffer;
+       }
+       if (!(p = xdr_encode_string(p, name))
         || !(p = xdr_encode_string(p, utsname()->nodename)))
                return ERR_PTR(-EIO);
        *p++ = htonl(argp->prog);
@@ -160,9 +181,11 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
        p = xdr_encode_common(rqstp, p, argp);
        if (IS_ERR(p))
                return PTR_ERR(p);
+
+       /* Surprise - there may even be room for an IPv6 address now */
        *p++ = argp->addr;
-       *p++ = argp->vers;
-       *p++ = argp->proto;
+       *p++ = 0;
+       *p++ = 0;
        *p++ = 0;
        rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
        return 0;
index 3cc369e5693f2d9af1c34e605c1ba2c615a21eae..634139232aafae89c3e14b9ceaf7fa8ee13e5bd2 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/sunrpc/svcsock.h>
 #include <net/ip.h>
 #include <linux/lockd/lockd.h>
+#include <linux/lockd/sm_inter.h>
 #include <linux/nfs.h>
 
 #define NLMDBG_FACILITY                NLMDBG_SVC
@@ -61,6 +62,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit);
 static unsigned long           nlm_grace_period;
 static unsigned long           nlm_timeout = LOCKD_DFLT_TIMEO;
 static int                     nlm_udpport, nlm_tcpport;
+int                            nsm_use_hostnames = 0;
 
 /*
  * Constants needed for the sysctl interface.
@@ -395,6 +397,22 @@ static ctl_table nlm_sysctls[] = {
                .extra1         = (int *) &nlm_port_min,
                .extra2         = (int *) &nlm_port_max,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nsm_use_hostnames",
+               .data           = &nsm_use_hostnames,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nsm_local_state",
+               .data           = &nsm_local_state,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };
 
@@ -483,6 +501,7 @@ module_param_call(nlm_udpport, param_set_port, param_get_int,
                  &nlm_udpport, 0644);
 module_param_call(nlm_tcpport, param_set_port, param_get_int,
                  &nlm_tcpport, 0644);
+module_param(nsm_use_hostnames, bool, 0644);
 
 /*
  * Initialising and terminating the module.
index a2dd9ccb9b321057b2dd414198e3eba6ce2e3bca..fa370f6eb07b27ddf2b1dc2b984ed5633b3d7c82 100644 (file)
@@ -38,8 +38,8 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
                return nlm_lck_denied_nolocks;
 
        /* Obtain host handle */
-       if (!(host = nlmsvc_lookup_host(rqstp))
-        || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
+       if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
+        || (argp->monitor && nsm_monitor(host) < 0))
                goto no_locks;
        *hostp = host;
 
@@ -260,7 +260,9 @@ static int nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *a
        struct nlm_rqst *call;
        int stat;
 
-       host = nlmsvc_lookup_host(rqstp);
+       host = nlmsvc_lookup_host(rqstp,
+                                 argp->lock.caller,
+                                 argp->lock.len);
        if (host == NULL)
                return rpc_system_err;
 
@@ -420,10 +422,6 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                                              void              *resp)
 {
        struct sockaddr_in      saddr = rqstp->rq_addr;
-       int                     vers = argp->vers;
-       int                     prot = argp->proto >> 1;
-
-       struct nlm_host         *host;
 
        dprintk("lockd: SM_NOTIFY     called\n");
        if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
@@ -438,21 +436,10 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
        /* Obtain the host pointer for this NFS server and try to
         * reclaim all locks we hold on this server.
         */
+       memset(&saddr, 0, sizeof(saddr));
        saddr.sin_addr.s_addr = argp->addr;
+       nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
 
-       if ((argp->proto & 1)==0) {
-               if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
-                       nlmclnt_recovery(host, argp->state);
-                       nlm_release_host(host);
-               }
-       } else {
-               /* If we run on an NFS server, delete all locks held by the client */
-
-               if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
-                       nlmsvc_free_host_resources(host);
-                       nlm_release_host(host);
-               }
-       }
        return rpc_success;
 }
 
@@ -468,7 +455,7 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
 
         dprintk("lockd: GRANTED_RES   called\n");
 
-        nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
+        nlmsvc_grant_reply(&argp->cookie, argp->status);
         return rpc_success;
 }
 
index 93c00ee7189d739f07f60ddf119cc719a4ce4146..814c6064c9e0514fef4a712a2f1be156afb7fb25 100644 (file)
@@ -40,7 +40,7 @@
 
 static void nlmsvc_release_block(struct nlm_block *block);
 static void    nlmsvc_insert_block(struct nlm_block *block, unsigned long);
-static int     nlmsvc_remove_block(struct nlm_block *block);
+static void    nlmsvc_remove_block(struct nlm_block *block);
 
 static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock);
 static void nlmsvc_freegrantargs(struct nlm_rqst *call);
@@ -49,7 +49,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops;
 /*
  * The list of blocked locks to retry
  */
-static struct nlm_block *      nlm_blocked;
+static LIST_HEAD(nlm_blocked);
 
 /*
  * Insert a blocked lock into the global list
@@ -57,48 +57,44 @@ static struct nlm_block *   nlm_blocked;
 static void
 nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
 {
-       struct nlm_block **bp, *b;
+       struct nlm_block *b;
+       struct list_head *pos;
 
        dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when);
-       kref_get(&block->b_count);
-       if (block->b_queued)
-               nlmsvc_remove_block(block);
-       bp = &nlm_blocked;
+       if (list_empty(&block->b_list)) {
+               kref_get(&block->b_count);
+       } else {
+               list_del_init(&block->b_list);
+       }
+
+       pos = &nlm_blocked;
        if (when != NLM_NEVER) {
                if ((when += jiffies) == NLM_NEVER)
                        when ++;
-               while ((b = *bp) && time_before_eq(b->b_when,when) && b->b_when != NLM_NEVER)
-                       bp = &b->b_next;
-       } else
-               while ((b = *bp) != 0)
-                       bp = &b->b_next;
+               list_for_each(pos, &nlm_blocked) {
+                       b = list_entry(pos, struct nlm_block, b_list);
+                       if (time_after(b->b_when,when) || b->b_when == NLM_NEVER)
+                               break;
+               }
+               /* On normal exit from the loop, pos == &nlm_blocked,
+                * so we will be adding to the end of the list - good
+                */
+       }
 
-       block->b_queued = 1;
+       list_add_tail(&block->b_list, pos);
        block->b_when = when;
-       block->b_next = b;
-       *bp = block;
 }
 
 /*
  * Remove a block from the global list
  */
-static int
+static inline void
 nlmsvc_remove_block(struct nlm_block *block)
 {
-       struct nlm_block **bp, *b;
-
-       if (!block->b_queued)
-               return 1;
-       for (bp = &nlm_blocked; (b = *bp) != 0; bp = &b->b_next) {
-               if (b == block) {
-                       *bp = block->b_next;
-                       block->b_queued = 0;
-                       nlmsvc_release_block(block);
-                       return 1;
-               }
+       if (!list_empty(&block->b_list)) {
+               list_del_init(&block->b_list);
+               nlmsvc_release_block(block);
        }
-
-       return 0;
 }
 
 /*
@@ -107,14 +103,14 @@ nlmsvc_remove_block(struct nlm_block *block)
 static struct nlm_block *
 nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
 {
-       struct nlm_block        **head, *block;
+       struct nlm_block        *block;
        struct file_lock        *fl;
 
        dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
                                file, lock->fl.fl_pid,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end, lock->fl.fl_type);
-       for (head = &nlm_blocked; (block = *head) != 0; head = &block->b_next) {
+       list_for_each_entry(block, &nlm_blocked, b_list) {
                fl = &block->b_call->a_args.lock.fl;
                dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
                                block->b_file, fl->fl_pid,
@@ -143,20 +139,20 @@ static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b)
  * Find a block with a given NLM cookie.
  */
 static inline struct nlm_block *
-nlmsvc_find_block(struct nlm_cookie *cookie,  struct sockaddr_in *sin)
+nlmsvc_find_block(struct nlm_cookie *cookie)
 {
        struct nlm_block *block;
 
-       for (block = nlm_blocked; block; block = block->b_next) {
-               dprintk("cookie: head of blocked queue %p, block %p\n", 
-                       nlm_blocked, block);
-               if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie)
-                               && nlm_cmp_addr(sin, &block->b_host->h_addr))
-                       break;
+       list_for_each_entry(block, &nlm_blocked, b_list) {
+               if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
+                       goto found;
        }
 
-       if (block != NULL)
-               kref_get(&block->b_count);
+       return NULL;
+
+found:
+       dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
+       kref_get(&block->b_count);
        return block;
 }
 
@@ -169,6 +165,11 @@ nlmsvc_find_block(struct nlm_cookie *cookie,  struct sockaddr_in *sin)
  * request, but (as I found out later) that's because some implementations
  * do just this. Never mind the standards comittees, they support our
  * logging industries.
+ *
+ * 10 years later: I hope we can safely ignore these old and broken
+ * clients by now. Let's fix this so we can uniquely identify an incoming
+ * GRANTED_RES message by cookie, without having to rely on the client's IP
+ * address. --okir
  */
 static inline struct nlm_block *
 nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
@@ -179,7 +180,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
        struct nlm_rqst         *call = NULL;
 
        /* Create host handle for callback */
-       host = nlmsvc_lookup_host(rqstp);
+       host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
        if (host == NULL)
                return NULL;
 
@@ -192,6 +193,8 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
        if (block == NULL)
                goto failed;
        kref_init(&block->b_count);
+       INIT_LIST_HEAD(&block->b_list);
+       INIT_LIST_HEAD(&block->b_flist);
 
        if (!nlmsvc_setgrantargs(call, lock))
                goto failed_free;
@@ -199,7 +202,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
        /* Set notifier function for VFS, and init args */
        call->a_args.lock.fl.fl_flags |= FL_SLEEP;
        call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations;
-       call->a_args.cookie = *cookie;  /* see above */
+       nlmclnt_next_cookie(&call->a_args.cookie);
 
        dprintk("lockd: created block %p...\n", block);
 
@@ -210,8 +213,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
        file->f_count++;
 
        /* Add to file's list of blocks */
-       block->b_fnext  = file->f_blocks;
-       file->f_blocks  = block;
+       list_add(&block->b_flist, &file->f_blocks);
 
        /* Set up RPC arguments for callback */
        block->b_call = call;
@@ -248,19 +250,13 @@ static void nlmsvc_free_block(struct kref *kref)
 {
        struct nlm_block *block = container_of(kref, struct nlm_block, b_count);
        struct nlm_file         *file = block->b_file;
-       struct nlm_block        **bp;
 
        dprintk("lockd: freeing block %p...\n", block);
 
-       down(&file->f_sema);
        /* Remove block from file's list of blocks */
-       for (bp = &file->f_blocks; *bp; bp = &(*bp)->b_fnext) {
-               if (*bp == block) {
-                       *bp = block->b_fnext;
-                       break;
-               }
-       }
-       up(&file->f_sema);
+       mutex_lock(&file->f_mutex);
+       list_del_init(&block->b_flist);
+       mutex_unlock(&file->f_mutex);
 
        nlmsvc_freegrantargs(block->b_call);
        nlm_release_call(block->b_call);
@@ -274,47 +270,32 @@ static void nlmsvc_release_block(struct nlm_block *block)
                kref_put(&block->b_count, nlmsvc_free_block);
 }
 
-static void nlmsvc_act_mark(struct nlm_host *host, struct nlm_file *file)
-{
-       struct nlm_block *block;
-
-       down(&file->f_sema);
-       for (block = file->f_blocks; block != NULL; block = block->b_fnext)
-               block->b_host->h_inuse = 1;
-       up(&file->f_sema);
-}
-
-static void nlmsvc_act_unlock(struct nlm_host *host, struct nlm_file *file)
+/*
+ * Loop over all blocks and delete blocks held by
+ * a matching host.
+ */
+void nlmsvc_traverse_blocks(struct nlm_host *host,
+                       struct nlm_file *file,
+                       nlm_host_match_fn_t match)
 {
-       struct nlm_block *block;
+       struct nlm_block *block, *next;
 
 restart:
-       down(&file->f_sema);
-       for (block = file->f_blocks; block != NULL; block = block->b_fnext) {
-               if (host != NULL && host != block->b_host)
+       mutex_lock(&file->f_mutex);
+       list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
+               if (!match(block->b_host, host))
                        continue;
-               if (!block->b_queued)
+               /* Do not destroy blocks that are not on
+                * the global retry list - why? */
+               if (list_empty(&block->b_list))
                        continue;
                kref_get(&block->b_count);
-               up(&file->f_sema);
+               mutex_unlock(&file->f_mutex);
                nlmsvc_unlink_block(block);
                nlmsvc_release_block(block);
                goto restart;
        }
-       up(&file->f_sema);
-}
-
-/*
- * Loop over all blocks and perform the action specified.
- * (NLM_ACT_CHECK handled by nlmsvc_inspect_file).
- */
-void
-nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
-{
-       if (action == NLM_ACT_MARK)
-               nlmsvc_act_mark(host, file);
-       else
-               nlmsvc_act_unlock(host, file);
+       mutex_unlock(&file->f_mutex);
 }
 
 /*
@@ -373,7 +354,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
        lock->fl.fl_flags &= ~FL_SLEEP;
 again:
        /* Lock file against concurrent access */
-       down(&file->f_sema);
+       mutex_lock(&file->f_mutex);
        /* Get existing block (in case client is busy-waiting) */
        block = nlmsvc_lookup_block(file, lock);
        if (block == NULL) {
@@ -411,10 +392,10 @@ again:
 
        /* If we don't have a block, create and initialize it. Then
         * retry because we may have slept in kmalloc. */
-       /* We have to release f_sema as nlmsvc_create_block may try to
+       /* We have to release f_mutex as nlmsvc_create_block may try to
         * to claim it while doing host garbage collection */
        if (newblock == NULL) {
-               up(&file->f_sema);
+               mutex_unlock(&file->f_mutex);
                dprintk("lockd: blocking on this lock (allocating).\n");
                if (!(newblock = nlmsvc_create_block(rqstp, file, lock, cookie)))
                        return nlm_lck_denied_nolocks;
@@ -424,7 +405,7 @@ again:
        /* Append to list of blocked */
        nlmsvc_insert_block(newblock, NLM_NEVER);
 out:
-       up(&file->f_sema);
+       mutex_unlock(&file->f_mutex);
        nlmsvc_release_block(newblock);
        nlmsvc_release_block(block);
        dprintk("lockd: nlmsvc_lock returned %u\n", ret);
@@ -451,6 +432,7 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
                                (long long)conflock->fl.fl_start,
                                (long long)conflock->fl.fl_end);
                conflock->caller = "somehost";  /* FIXME */
+               conflock->len = strlen(conflock->caller);
                conflock->oh.len = 0;           /* don't return OH info */
                conflock->svid = conflock->fl.fl_pid;
                return nlm_lck_denied;
@@ -507,9 +489,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end);
 
-       down(&file->f_sema);
+       mutex_lock(&file->f_mutex);
        block = nlmsvc_lookup_block(file, lock);
-       up(&file->f_sema);
+       mutex_unlock(&file->f_mutex);
        if (block != NULL) {
                status = nlmsvc_unlink_block(block);
                nlmsvc_release_block(block);
@@ -527,10 +509,10 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
 static void
 nlmsvc_notify_blocked(struct file_lock *fl)
 {
-       struct nlm_block        **bp, *block;
+       struct nlm_block        *block;
 
        dprintk("lockd: VFS unblock notification for block %p\n", fl);
-       for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) {
+       list_for_each_entry(block, &nlm_blocked, b_list) {
                if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
                        nlmsvc_insert_block(block, 0);
                        svc_wake_up(block->b_daemon);
@@ -663,17 +645,14 @@ static const struct rpc_call_ops nlmsvc_grant_ops = {
  * block.
  */
 void
-nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status)
+nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
 {
        struct nlm_block        *block;
-       struct nlm_file         *file;
 
-       dprintk("grant_reply: looking for cookie %x, host (%08x), s=%d \n", 
-               *(unsigned int *)(cookie->data), 
-               ntohl(rqstp->rq_addr.sin_addr.s_addr), status);
-       if (!(block = nlmsvc_find_block(cookie, &rqstp->rq_addr)))
+       dprintk("grant_reply: looking for cookie %x, s=%d \n",
+               *(unsigned int *)(cookie->data), status);
+       if (!(block = nlmsvc_find_block(cookie)))
                return;
-       file = block->b_file;
 
        if (block) {
                if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
@@ -696,16 +675,19 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status
 unsigned long
 nlmsvc_retry_blocked(void)
 {
-       struct nlm_block        *block;
+       unsigned long   timeout = MAX_SCHEDULE_TIMEOUT;
+       struct nlm_block *block;
+
+       while (!list_empty(&nlm_blocked)) {
+               block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
 
-       dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
-                       nlm_blocked,
-                       nlm_blocked? nlm_blocked->b_when : 0);
-       while ((block = nlm_blocked) != 0) {
                if (block->b_when == NLM_NEVER)
                        break;
-               if (time_after(block->b_when,jiffies))
+               if (time_after(block->b_when,jiffies)) {
+                       timeout = block->b_when - jiffies;
                        break;
+               }
+
                dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
                        block, block->b_when);
                kref_get(&block->b_count);
@@ -713,8 +695,5 @@ nlmsvc_retry_blocked(void)
                nlmsvc_release_block(block);
        }
 
-       if ((block = nlm_blocked) && block->b_when != NLM_NEVER)
-               return (block->b_when - jiffies);
-
-       return MAX_SCHEDULE_TIMEOUT;
+       return timeout;
 }
index dbb66a3b5cd97ddd49f0b83a71fa177f31b8ec04..75b2c81bcb93c01782710b7a36fc501aea42ca9a 100644 (file)
@@ -66,8 +66,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
                return nlm_lck_denied_nolocks;
 
        /* Obtain host handle */
-       if (!(host = nlmsvc_lookup_host(rqstp))
-        || (argp->monitor && !host->h_monitored && nsm_monitor(host) < 0))
+       if (!(host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len))
+        || (argp->monitor && nsm_monitor(host) < 0))
                goto no_locks;
        *hostp = host;
 
@@ -287,7 +287,9 @@ static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *ar
        struct nlm_rqst *call;
        int stat;
 
-       host = nlmsvc_lookup_host(rqstp);
+       host = nlmsvc_lookup_host(rqstp,
+                                 argp->lock.caller,
+                                 argp->lock.len);
        if (host == NULL)
                return rpc_system_err;
 
@@ -449,9 +451,6 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                                              void              *resp)
 {
        struct sockaddr_in      saddr = rqstp->rq_addr;
-       int                     vers = argp->vers;
-       int                     prot = argp->proto >> 1;
-       struct nlm_host         *host;
 
        dprintk("lockd: SM_NOTIFY     called\n");
        if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
@@ -466,19 +465,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
        /* Obtain the host pointer for this NFS server and try to
         * reclaim all locks we hold on this server.
         */
+       memset(&saddr, 0, sizeof(saddr));
        saddr.sin_addr.s_addr = argp->addr;
-       if ((argp->proto & 1)==0) {
-               if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
-                       nlmclnt_recovery(host, argp->state);
-                       nlm_release_host(host);
-               }
-       } else {
-               /* If we run on an NFS server, delete all locks held by the client */
-               if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
-                       nlmsvc_free_host_resources(host);
-                       nlm_release_host(host);
-               }
-       }
+       nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
 
        return rpc_success;
 }
@@ -495,7 +484,7 @@ nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
 
        dprintk("lockd: GRANTED_RES   called\n");
 
-       nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
+       nlmsvc_grant_reply(&argp->cookie, argp->status);
        return rpc_success;
 }
 
index 27288c83da9689ec5bae8cb9d2f71ee143120b3b..b9926ce8782e86b7782ab752e61474af35806cca 100644 (file)
@@ -85,24 +85,20 @@ nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file,
 }
 
 /*
- * Traverse all shares for a given file (and host).
- * NLM_ACT_CHECK is handled by nlmsvc_inspect_file.
+ * Traverse all shares for a given file, and delete
+ * those owned by the given (type of) host
  */
-void
-nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file, int action)
+void nlmsvc_traverse_shares(struct nlm_host *host, struct nlm_file *file,
+               nlm_host_match_fn_t match)
 {
        struct nlm_share        *share, **shpp;
 
        shpp = &file->f_shares;
        while ((share = *shpp) !=  NULL) {
-               if (action == NLM_ACT_MARK)
-                       share->s_host->h_inuse = 1;
-               else if (action == NLM_ACT_UNLOCK) {
-                       if (host == NULL || host == share->s_host) {
-                               *shpp = share->s_next;
-                               kfree(share);
-                               continue;
-                       }
+               if (match(share->s_host, host)) {
+                       *shpp = share->s_next;
+                       kfree(share);
+                       continue;
                }
                shpp = &share->s_next;
        }
index a92dd98f84013dbece84aa0367f7ed869f487c92..514f5f20701ea3d3cc8ba0410dd8fd3098e71c87 100644 (file)
@@ -25,9 +25,9 @@
 /*
  * Global file hash table
  */
-#define FILE_HASH_BITS         5
+#define FILE_HASH_BITS         7
 #define FILE_NRHASH            (1<<FILE_HASH_BITS)
-static struct nlm_file *       nlm_files[FILE_NRHASH];
+static struct hlist_head       nlm_files[FILE_NRHASH];
 static DEFINE_MUTEX(nlm_file_mutex);
 
 #ifdef NFSD_DEBUG
@@ -82,6 +82,7 @@ u32
 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
                                        struct nfs_fh *f)
 {
+       struct hlist_node *pos;
        struct nlm_file *file;
        unsigned int    hash;
        u32             nfserr;
@@ -93,7 +94,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
        /* Lock file table */
        mutex_lock(&nlm_file_mutex);
 
-       for (file = nlm_files[hash]; file; file = file->f_next)
+       hlist_for_each_entry(file, pos, &nlm_files[hash], f_list)
                if (!nfs_compare_fh(&file->f_handle, f))
                        goto found;
 
@@ -105,8 +106,9 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
                goto out_unlock;
 
        memcpy(&file->f_handle, f, sizeof(struct nfs_fh));
-       file->f_hash = hash;
-       init_MUTEX(&file->f_sema);
+       mutex_init(&file->f_mutex);
+       INIT_HLIST_NODE(&file->f_list);
+       INIT_LIST_HEAD(&file->f_blocks);
 
        /* Open the file. Note that this must not sleep for too long, else
         * we would lock up lockd:-) So no NFS re-exports, folks.
@@ -115,12 +117,11 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
         * the file.
         */
        if ((nfserr = nlmsvc_ops->fopen(rqstp, f, &file->f_file)) != 0) {
-               dprintk("lockd: open failed (nfserr %d)\n", ntohl(nfserr));
+               dprintk("lockd: open failed (error %d)\n", nfserr);
                goto out_free;
        }
 
-       file->f_next = nlm_files[hash];
-       nlm_files[hash] = file;
+       hlist_add_head(&file->f_list, &nlm_files[hash]);
 
 found:
        dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
@@ -149,22 +150,14 @@ out_free:
 static inline void
 nlm_delete_file(struct nlm_file *file)
 {
-       struct nlm_file **fp, *f;
-
        nlm_debug_print_file("closing file", file);
-
-       fp = nlm_files + file->f_hash;
-       while ((f = *fp) != NULL) {
-               if (f == file) {
-                       *fp = file->f_next;
-                       nlmsvc_ops->fclose(file->f_file);
-                       kfree(file);
-                       return;
-               }
-               fp = &f->f_next;
+       if (!hlist_unhashed(&file->f_list)) {
+               hlist_del(&file->f_list);
+               nlmsvc_ops->fclose(file->f_file);
+               kfree(file);
+       } else {
+               printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
        }
-
-       printk(KERN_WARNING "lockd: attempt to release unknown file!\n");
 }
 
 /*
@@ -172,7 +165,8 @@ nlm_delete_file(struct nlm_file *file)
  * action.
  */
 static int
-nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, int action)
+nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file,
+                       nlm_host_match_fn_t match)
 {
        struct inode     *inode = nlmsvc_file_inode(file);
        struct file_lock *fl;
@@ -186,17 +180,11 @@ again:
 
                /* update current lock count */
                file->f_locks++;
+
                lockhost = (struct nlm_host *) fl->fl_owner;
-               if (action == NLM_ACT_MARK)
-                       lockhost->h_inuse = 1;
-               else if (action == NLM_ACT_CHECK)
-                       return 1;
-               else if (action == NLM_ACT_UNLOCK) {
+               if (match(lockhost, host)) {
                        struct file_lock lock = *fl;
 
-                       if (host && lockhost != host)
-                               continue;
-
                        lock.fl_type  = F_UNLCK;
                        lock.fl_start = 0;
                        lock.fl_end   = OFFSET_MAX;
@@ -213,53 +201,66 @@ again:
 }
 
 /*
- * Operate on a single file
+ * Inspect a single file
  */
 static inline int
-nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, int action)
+nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, nlm_host_match_fn_t match)
 {
-       if (action == NLM_ACT_CHECK) {
-               /* Fast path for mark and sweep garbage collection */
-               if (file->f_count || file->f_blocks || file->f_shares)
+       nlmsvc_traverse_blocks(host, file, match);
+       nlmsvc_traverse_shares(host, file, match);
+       return nlm_traverse_locks(host, file, match);
+}
+
+/*
+ * Quick check whether there are still any locks, blocks or
+ * shares on a given file.
+ */
+static inline int
+nlm_file_inuse(struct nlm_file *file)
+{
+       struct inode     *inode = nlmsvc_file_inode(file);
+       struct file_lock *fl;
+
+       if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares)
+               return 1;
+
+       for (fl = inode->i_flock; fl; fl = fl->fl_next) {
+               if (fl->fl_lmops == &nlmsvc_lock_operations)
                        return 1;
-       } else {
-               nlmsvc_traverse_blocks(host, file, action);
-               nlmsvc_traverse_shares(host, file, action);
        }
-       return nlm_traverse_locks(host, file, action);
+       file->f_locks = 0;
+       return 0;
 }
 
 /*
  * Loop over all files in the file table.
  */
 static int
-nlm_traverse_files(struct nlm_host *host, int action)
+nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match)
 {
-       struct nlm_file *file, **fp;
+       struct hlist_node *pos, *next;
+       struct nlm_file *file;
        int i, ret = 0;
 
        mutex_lock(&nlm_file_mutex);
        for (i = 0; i < FILE_NRHASH; i++) {
-               fp = nlm_files + i;
-               while ((file = *fp) != NULL) {
+               hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) {
                        file->f_count++;
                        mutex_unlock(&nlm_file_mutex);
 
                        /* Traverse locks, blocks and shares of this file
                         * and update file->f_locks count */
-                       if (nlm_inspect_file(host, file, action))
+                       if (nlm_inspect_file(host, file, match))
                                ret = 1;
 
                        mutex_lock(&nlm_file_mutex);
                        file->f_count--;
                        /* No more references to this file. Let go of it. */
-                       if (!file->f_blocks && !file->f_locks
+                       if (list_empty(&file->f_blocks) && !file->f_locks
                         && !file->f_shares && !file->f_count) {
-                               *fp = file->f_next;
+                               hlist_del(&file->f_list);
                                nlmsvc_ops->fclose(file->f_file);
                                kfree(file);
-                       } else {
-                               fp = &file->f_next;
                        }
                }
        }
@@ -286,14 +287,46 @@ nlm_release_file(struct nlm_file *file)
        mutex_lock(&nlm_file_mutex);
 
        /* If there are no more locks etc, delete the file */
-       if(--file->f_count == 0) {
-               if(!nlm_inspect_file(NULL, file, NLM_ACT_CHECK))
-                       nlm_delete_file(file);
-       }
+       if (--file->f_count == 0 && !nlm_file_inuse(file))
+               nlm_delete_file(file);
 
        mutex_unlock(&nlm_file_mutex);
 }
 
+/*
+ * Helpers function for resource traversal
+ *
+ * nlmsvc_mark_host:
+ *     used by the garbage collector; simply sets h_inuse.
+ *     Always returns 0.
+ *
+ * nlmsvc_same_host:
+ *     returns 1 iff the two hosts match. Used to release
+ *     all resources bound to a specific host.
+ *
+ * nlmsvc_is_client:
+ *     returns 1 iff the host is a client.
+ *     Used by nlmsvc_invalidate_all
+ */
+static int
+nlmsvc_mark_host(struct nlm_host *host, struct nlm_host *dummy)
+{
+       host->h_inuse = 1;
+       return 0;
+}
+
+static int
+nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other)
+{
+       return host == other;
+}
+
+static int
+nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy)
+{
+       return host->h_server;
+}
+
 /*
  * Mark all hosts that still hold resources
  */
@@ -301,8 +334,7 @@ void
 nlmsvc_mark_resources(void)
 {
        dprintk("lockd: nlmsvc_mark_resources\n");
-
-       nlm_traverse_files(NULL, NLM_ACT_MARK);
+       nlm_traverse_files(NULL, nlmsvc_mark_host);
 }
 
 /*
@@ -313,23 +345,25 @@ nlmsvc_free_host_resources(struct nlm_host *host)
 {
        dprintk("lockd: nlmsvc_free_host_resources\n");
 
-       if (nlm_traverse_files(host, NLM_ACT_UNLOCK))
+       if (nlm_traverse_files(host, nlmsvc_same_host)) {
                printk(KERN_WARNING
-                       "lockd: couldn't remove all locks held by %s",
+                       "lockd: couldn't remove all locks held by %s\n",
                        host->h_name);
+               BUG();
+       }
 }
 
 /*
- * delete all hosts structs for clients
+ * Remove all locks held for clients
  */
 void
 nlmsvc_invalidate_all(void)
 {
-       struct nlm_host *host;
-       while ((host = nlm_find_client()) != NULL) {
-               nlmsvc_free_host_resources(host);
-               host->h_expires = 0;
-               host->h_killed = 1;
-               nlm_release_host(host);
-       }
+       /* Release all locks held by NFS clients.
+        * Previously, the code would call
+        * nlmsvc_free_host_resources for each client in
+        * turn, which is about as inefficient as it gets.
+        * Now we just do it once in nlm_traverse_files.
+        */
+       nlm_traverse_files(NULL, nlmsvc_is_client);
 }
index cfe141e5d7592630a58edd15447b1e023b99b04a..e13fa23bd108a2f8b86b9e3388a46509a003da64 100644 (file)
@@ -319,12 +319,25 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
 
 static struct cache_head *export_table[EXPORT_HASHMAX];
 
+static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
+{
+       int i;
+
+       for (i = 0; i < fsloc->locations_count; i++) {
+               kfree(fsloc->locations[i].path);
+               kfree(fsloc->locations[i].hosts);
+       }
+       kfree(fsloc->locations);
+}
+
 static void svc_export_put(struct kref *ref)
 {
        struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
        dput(exp->ex_dentry);
        mntput(exp->ex_mnt);
        auth_domain_put(exp->ex_client);
+       kfree(exp->ex_path);
+       nfsd4_fslocs_free(&exp->ex_fslocs);
        kfree(exp);
 }
 
@@ -386,6 +399,69 @@ static int check_export(struct inode *inode, int flags)
 
 }
 
+#ifdef CONFIG_NFSD_V4
+
+static int
+fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
+{
+       int len;
+       int migrated, i, err;
+
+       len = qword_get(mesg, buf, PAGE_SIZE);
+       if (len != 5 || memcmp(buf, "fsloc", 5))
+               return 0;
+
+       /* listsize */
+       err = get_int(mesg, &fsloc->locations_count);
+       if (err)
+               return err;
+       if (fsloc->locations_count > MAX_FS_LOCATIONS)
+               return -EINVAL;
+       if (fsloc->locations_count == 0)
+               return 0;
+
+       fsloc->locations = kzalloc(fsloc->locations_count
+                       * sizeof(struct nfsd4_fs_location), GFP_KERNEL);
+       if (!fsloc->locations)
+               return -ENOMEM;
+       for (i=0; i < fsloc->locations_count; i++) {
+               /* colon separated host list */
+               err = -EINVAL;
+               len = qword_get(mesg, buf, PAGE_SIZE);
+               if (len <= 0)
+                       goto out_free_all;
+               err = -ENOMEM;
+               fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
+               if (!fsloc->locations[i].hosts)
+                       goto out_free_all;
+               err = -EINVAL;
+               /* slash separated path component list */
+               len = qword_get(mesg, buf, PAGE_SIZE);
+               if (len <= 0)
+                       goto out_free_all;
+               err = -ENOMEM;
+               fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
+               if (!fsloc->locations[i].path)
+                       goto out_free_all;
+       }
+       /* migrated */
+       err = get_int(mesg, &migrated);
+       if (err)
+               goto out_free_all;
+       err = -EINVAL;
+       if (migrated < 0 || migrated > 1)
+               goto out_free_all;
+       fsloc->migrated = migrated;
+       return 0;
+out_free_all:
+       nfsd4_fslocs_free(fsloc);
+       return err;
+}
+
+#else /* CONFIG_NFSD_V4 */
+static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; }
+#endif
+
 static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 {
        /* client path expiry [flags anonuid anongid fsid] */
@@ -398,6 +474,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        int an_int;
 
        nd.dentry = NULL;
+       exp.ex_path = NULL;
 
        if (mesg[mlen-1] != '\n')
                return -EINVAL;
@@ -428,6 +505,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        exp.ex_client = dom;
        exp.ex_mnt = nd.mnt;
        exp.ex_dentry = nd.dentry;
+       exp.ex_path = kstrdup(buf, GFP_KERNEL);
+       err = -ENOMEM;
+       if (!exp.ex_path)
+               goto out;
 
        /* expiry */
        err = -EINVAL;
@@ -435,6 +516,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        if (exp.h.expiry_time == 0)
                goto out;
 
+       /* fs locations */
+       exp.ex_fslocs.locations = NULL;
+       exp.ex_fslocs.locations_count = 0;
+       exp.ex_fslocs.migrated = 0;
+
        /* flags */
        err = get_int(&mesg, &an_int);
        if (err == -ENOENT)
@@ -460,6 +546,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 
                err = check_export(nd.dentry->d_inode, exp.ex_flags);
                if (err) goto out;
+
+               err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
+               if (err)
+                       goto out;
        }
 
        expp = svc_export_lookup(&exp);
@@ -473,6 +563,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        else
                exp_put(expp);
  out:
+       kfree(exp.ex_path);
        if (nd.dentry)
                path_release(&nd);
  out_no_path:
@@ -482,7 +573,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
        return err;
 }
 
-static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong);
+static void exp_flags(struct seq_file *m, int flag, int fsid,
+               uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs);
 
 static int svc_export_show(struct seq_file *m,
                           struct cache_detail *cd,
@@ -501,8 +593,8 @@ static int svc_export_show(struct seq_file *m,
        seq_putc(m, '(');
        if (test_bit(CACHE_VALID, &h->flags) && 
            !test_bit(CACHE_NEGATIVE, &h->flags))
-               exp_flags(m, exp->ex_flags, exp->ex_fsid, 
-                         exp->ex_anon_uid, exp->ex_anon_gid);
+               exp_flags(m, exp->ex_flags, exp->ex_fsid,
+                         exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
        seq_puts(m, ")\n");
        return 0;
 }
@@ -524,6 +616,10 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
        new->ex_client = item->ex_client;
        new->ex_dentry = dget(item->ex_dentry);
        new->ex_mnt = mntget(item->ex_mnt);
+       new->ex_path = NULL;
+       new->ex_fslocs.locations = NULL;
+       new->ex_fslocs.locations_count = 0;
+       new->ex_fslocs.migrated = 0;
 }
 
 static void export_update(struct cache_head *cnew, struct cache_head *citem)
@@ -535,6 +631,14 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
        new->ex_anon_uid = item->ex_anon_uid;
        new->ex_anon_gid = item->ex_anon_gid;
        new->ex_fsid = item->ex_fsid;
+       new->ex_path = item->ex_path;
+       item->ex_path = NULL;
+       new->ex_fslocs.locations = item->ex_fslocs.locations;
+       item->ex_fslocs.locations = NULL;
+       new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
+       item->ex_fslocs.locations_count = 0;
+       new->ex_fslocs.migrated = item->ex_fslocs.migrated;
+       item->ex_fslocs.migrated = 0;
 }
 
 static struct cache_head *svc_export_alloc(void)
@@ -1048,30 +1152,21 @@ int
 exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
               struct cache_req *creq)
 {
-       struct svc_expkey *fsid_key;
        struct svc_export *exp;
        int rv;
        u32 fsidv[2];
 
        mk_fsid_v1(fsidv, 0);
 
-       fsid_key = exp_find_key(clp, 1, fsidv, creq);
-       if (IS_ERR(fsid_key) && PTR_ERR(fsid_key) == -EAGAIN)
+       exp = exp_find(clp, 1, fsidv, creq);
+       if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
                return nfserr_dropit;
-       if (!fsid_key || IS_ERR(fsid_key))
-               return nfserr_perm;
-
-       exp = exp_get_by_name(clp, fsid_key->ek_mnt, fsid_key->ek_dentry, creq);
        if (exp == NULL)
-               rv = nfserr_perm;
+               return nfserr_perm;
        else if (IS_ERR(exp))
-               rv = nfserrno(PTR_ERR(exp));
-       else {
-               rv = fh_compose(fhp, exp,
-                               fsid_key->ek_dentry, NULL);
-               exp_put(exp);
-       }
-       cache_put(&fsid_key->h, &svc_expkey_cache);
+               return nfserrno(PTR_ERR(exp));
+       rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
+       exp_put(exp);
        return rv;
 }
 
@@ -1158,7 +1253,8 @@ static struct flags {
        { 0, {"", ""}}
 };
 
-static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong)
+static void exp_flags(struct seq_file *m, int flag, int fsid,
+               uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc)
 {
        int first = 0;
        struct flags *flg;
@@ -1174,6 +1270,21 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t
                seq_printf(m, "%sanonuid=%d", first++?",":"", anonu);
        if (anong != (gid_t)-2 && anong != (0x10000-2))
                seq_printf(m, "%sanongid=%d", first++?",":"", anong);
+       if (fsloc && fsloc->locations_count > 0) {
+               char *loctype = (fsloc->migrated) ? "refer" : "replicas";
+               int i;
+
+               seq_printf(m, "%s%s=", first++?",":"", loctype);
+               seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
+               seq_putc(m, '@');
+               seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
+               for (i = 1; i < fsloc->locations_count; i++) {
+                       seq_putc(m, ';');
+                       seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
+                       seq_putc(m, '@');
+                       seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
+               }
+       }
 }
 
 static int e_show(struct seq_file *m, void *p)
index fc95c4df66934e4fe420aada6f1feac601ee8f92..9187755661df06d9aec879a08167e9848c26c399 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nfsd/nfsacl.c
+ * linux/fs/nfsd/nfs2acl.c
  *
  * Process version 2 NFSACL requests.
  *
@@ -241,7 +241,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
 
        rqstp->rq_res.page_len = w;
        while (w > 0) {
-               if (!svc_take_res_page(rqstp))
+               if (!rqstp->rq_respages[rqstp->rq_resused++])
                        return 0;
                w -= PAGE_SIZE;
        }
@@ -333,4 +333,5 @@ struct svc_version  nfsd_acl_version2 = {
                .vs_proc        = nfsd_acl_procedures2,
                .vs_dispatch    = nfsd_dispatch,
                .vs_xdrsize     = NFS3_SVC_XDRSIZE,
+               .vs_hidden      = 1,
 };
index 16e10c170aedf33276def7ad26711bbe5ad4f6cc..d4bdc00c1169cc3f462a1fe11e2ebae0e72b15a9 100644 (file)
@@ -185,7 +185,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
 
                rqstp->rq_res.page_len = w;
                while (w > 0) {
-                       if (!svc_take_res_page(rqstp))
+                       if (!rqstp->rq_respages[rqstp->rq_resused++])
                                return 0;
                        w -= PAGE_SIZE;
                }
@@ -263,5 +263,6 @@ struct svc_version  nfsd_acl_version3 = {
                .vs_proc        = nfsd_acl_procedures3,
                .vs_dispatch    = nfsd_dispatch,
                .vs_xdrsize     = NFS3_SVC_XDRSIZE,
+               .vs_hidden      = 1,
 };
 
index f61142afea4490f5ebe542fe7ff167bf15a9564b..a5ebc7dbb3842d7d1a3f9a7de6256831a07d026b 100644 (file)
@@ -160,6 +160,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
                                        struct nfsd3_readres  *resp)
 {
        int     nfserr;
+       u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
                                SVCFH_fmt(&argp->fh),
@@ -172,15 +173,15 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
         */
 
        resp->count = argp->count;
-       if (NFSSVC_MAXBLKSIZE < resp->count)
-               resp->count = NFSSVC_MAXBLKSIZE;
+       if (max_blocksize < resp->count)
+               resp->count = max_blocksize;
 
        svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
 
        fh_copy(&resp->fh, &argp->fh);
        nfserr = nfsd_read(rqstp, &resp->fh, NULL,
                                  argp->offset,
-                                 argp->vec, argp->vlen,
+                                 rqstp->rq_vec, argp->vlen,
                                  &resp->count);
        if (nfserr == 0) {
                struct inode    *inode = resp->fh.fh_dentry->d_inode;
@@ -210,7 +211,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
        resp->committed = argp->stable;
        nfserr = nfsd_write(rqstp, &resp->fh, NULL,
                                   argp->offset,
-                                  argp->vec, argp->vlen,
+                                  rqstp->rq_vec, argp->vlen,
                                   argp->len,
                                   &resp->committed);
        resp->count = argp->count;
@@ -538,15 +539,16 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
                                           struct nfsd3_fsinfores *resp)
 {
        int     nfserr;
+       u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: FSINFO(3)   %s\n",
                                SVCFH_fmt(&argp->fh));
 
-       resp->f_rtmax  = NFSSVC_MAXBLKSIZE;
-       resp->f_rtpref = NFSSVC_MAXBLKSIZE;
+       resp->f_rtmax  = max_blocksize;
+       resp->f_rtpref = max_blocksize;
        resp->f_rtmult = PAGE_SIZE;
-       resp->f_wtmax  = NFSSVC_MAXBLKSIZE;
-       resp->f_wtpref = NFSSVC_MAXBLKSIZE;
+       resp->f_wtmax  = max_blocksize;
+       resp->f_wtpref = max_blocksize;
        resp->f_wtmult = PAGE_SIZE;
        resp->f_dtpref = PAGE_SIZE;
        resp->f_maxfilesize = ~(u32) 0;
index 243d94b9653a4efcf9804a0820a27bf676d16557..247d518248bf71b2a95b5ce04b460374dd88c51f 100644 (file)
@@ -330,6 +330,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
 {
        unsigned int len;
        int v,pn;
+       u32 max_blocksize = svc_max_payload(rqstp);
 
        if (!(p = decode_fh(p, &args->fh))
         || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -337,17 +338,16 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
 
        len = args->count = ntohl(*p++);
 
-       if (len > NFSSVC_MAXBLKSIZE)
-               len = NFSSVC_MAXBLKSIZE;
+       if (len > max_blocksize)
+               len = max_blocksize;
 
        /* set up the kvec */
        v=0;
        while (len > 0) {
-               pn = rqstp->rq_resused;
-               svc_take_page(rqstp);
-               args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
-               args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
-               len -= args->vec[v].iov_len;
+               pn = rqstp->rq_resused++;
+               rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
+               rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
+               len -= rqstp->rq_vec[v].iov_len;
                v++;
        }
        args->vlen = v;
@@ -359,6 +359,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_writeargs *args)
 {
        unsigned int len, v, hdr;
+       u32 max_blocksize = svc_max_payload(rqstp);
 
        if (!(p = decode_fh(p, &args->fh))
         || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -373,22 +374,22 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
            rqstp->rq_arg.len - hdr < len)
                return 0;
 
-       args->vec[0].iov_base = (void*)p;
-       args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
+       rqstp->rq_vec[0].iov_base = (void*)p;
+       rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
 
-       if (len > NFSSVC_MAXBLKSIZE)
-               len = NFSSVC_MAXBLKSIZE;
+       if (len > max_blocksize)
+               len = max_blocksize;
        v=  0;
-       while (len > args->vec[v].iov_len) {
-               len -= args->vec[v].iov_len;
+       while (len > rqstp->rq_vec[v].iov_len) {
+               len -= rqstp->rq_vec[v].iov_len;
                v++;
-               args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
-               args->vec[v].iov_len = PAGE_SIZE;
+               rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
+               rqstp->rq_vec[v].iov_len = PAGE_SIZE;
        }
-       args->vec[v].iov_len = len;
+       rqstp->rq_vec[v].iov_len = len;
        args->vlen = v+1;
 
-       return args->count == args->len && args->vec[0].iov_len > 0;
+       return args->count == args->len && rqstp->rq_vec[0].iov_len > 0;
 }
 
 int
@@ -446,11 +447,11 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
         * This page appears in the rq_res.pages list, but as pages_len is always
         * 0, it won't get in the way
         */
-       svc_take_page(rqstp);
        len = ntohl(*p++);
        if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
                return 0;
-       args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+       args->tname = new =
+               page_address(rqstp->rq_respages[rqstp->rq_resused++]);
        args->tlen = len;
        /* first copy and check from the first page */
        old = (char*)p;
@@ -522,8 +523,8 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p,
 {
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
-       svc_take_page(rqstp);
-       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+       args->buffer =
+               page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
        return xdr_argsize_check(rqstp, p);
 }
@@ -554,8 +555,8 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
        if (args->count > PAGE_SIZE)
                args->count = PAGE_SIZE;
 
-       svc_take_page(rqstp);
-       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+       args->buffer =
+               page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
        return xdr_argsize_check(rqstp, p);
 }
@@ -565,6 +566,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_readdirargs *args)
 {
        int len, pn;
+       u32 max_blocksize = svc_max_payload(rqstp);
 
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
@@ -573,13 +575,12 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
        args->dircount = ntohl(*p++);
        args->count    = ntohl(*p++);
 
-       len = (args->count > NFSSVC_MAXBLKSIZE) ? NFSSVC_MAXBLKSIZE :
+       len = (args->count > max_blocksize) ? max_blocksize :
                                                  args->count;
        args->count = len;
 
        while (len > 0) {
-               pn = rqstp->rq_resused;
-               svc_take_page(rqstp);
+               pn = rqstp->rq_resused++;
                if (!args->buffer)
                        args->buffer = page_address(rqstp->rq_respages[pn]);
                len -= PAGE_SIZE;
@@ -668,7 +669,6 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
                rqstp->rq_res.page_len = resp->len;
                if (resp->len & 3) {
                        /* need to pad the tail */
-                       rqstp->rq_restailpage = 0;
                        rqstp->rq_res.tail[0].iov_base = p;
                        *p = 0;
                        rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -693,7 +693,6 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
                rqstp->rq_res.page_len = resp->count;
                if (resp->count & 3) {
                        /* need to pad the tail */
-                       rqstp->rq_restailpage = 0;
                        rqstp->rq_res.tail[0].iov_base = p;
                        *p = 0;
                        rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
@@ -768,7 +767,6 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
                rqstp->rq_res.page_len = (resp->count) << 2;
 
                /* add the 'tail' to the end of the 'head' page - page 0. */
-               rqstp->rq_restailpage = 0;
                rqstp->rq_res.tail[0].iov_base = p;
                *p++ = 0;               /* no more entries */
                *p++ = htonl(resp->common.err == nfserr_eof);
index edb107e61b91d8583f18e1bc26fe8c63e066196a..5d94555cdc836a4f9ce2f0e998e2d5a734e1ca00 100644 (file)
@@ -63,6 +63,8 @@
 #define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
                | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
 
+#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS | NFS4_ACE_IDENTIFIER_GROUP)
+
 #define MASK_EQUAL(mask1, mask2) \
        ( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) )
 
@@ -96,24 +98,26 @@ deny_mask(u32 allow_mask, unsigned int flags)
 /* XXX: modify functions to return NFS errors; they're only ever
  * used by nfs code, after all.... */
 
-static int
-mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
+/* We only map from NFSv4 to POSIX ACLs when setting ACLs, when we err on the
+ * side of being more restrictive, so the mode bit mapping below is
+ * pessimistic.  An optimistic version would be needed to handle DENY's,
+ * but we espect to coalesce all ALLOWs and DENYs before mapping to mode
+ * bits. */
+
+static void
+low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
 {
-       u32 ignore = 0;
+       u32 write_mode = NFS4_WRITE_MODE;
 
-       if (!(flags & NFS4_ACL_DIR))
-               ignore |= NFS4_ACE_DELETE_CHILD; /* ignore it */
-       perm |= ignore;
+       if (flags & NFS4_ACL_DIR)
+               write_mode |= NFS4_ACE_DELETE_CHILD;
        *mode = 0;
        if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
                *mode |= ACL_READ;
-       if ((perm & NFS4_WRITE_MODE) == NFS4_WRITE_MODE)
+       if ((perm & write_mode) == write_mode)
                *mode |= ACL_WRITE;
        if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
                *mode |= ACL_EXECUTE;
-       if (!MASK_EQUAL(perm, ignore|mask_from_posix(*mode, flags)))
-               return -EINVAL;
-       return 0;
 }
 
 struct ace_container {
@@ -338,38 +342,6 @@ sort_pacl(struct posix_acl *pacl)
        return;
 }
 
-static int
-write_pace(struct nfs4_ace *ace, struct posix_acl *pacl,
-               struct posix_acl_entry **pace, short tag, unsigned int flags)
-{
-       struct posix_acl_entry *this = *pace;
-
-       if (*pace == pacl->a_entries + pacl->a_count)
-               return -EINVAL; /* fell off the end */
-       (*pace)++;
-       this->e_tag = tag;
-       if (tag == ACL_USER_OBJ)
-               flags |= NFS4_ACL_OWNER;
-       if (mode_from_nfs4(ace->access_mask, &this->e_perm, flags))
-               return -EINVAL;
-       this->e_id = (tag == ACL_USER || tag == ACL_GROUP ?
-                       ace->who : ACL_UNDEFINED_ID);
-       return 0;
-}
-
-static struct nfs4_ace *
-get_next_v4_ace(struct list_head **p, struct list_head *head)
-{
-       struct nfs4_ace *ace;
-
-       *p = (*p)->next;
-       if (*p == head)
-               return NULL;
-       ace = list_entry(*p, struct nfs4_ace, l_ace);
-
-       return ace;
-}
-
 int
 nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
                struct posix_acl **dpacl, unsigned int flags)
@@ -385,42 +357,23 @@ nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
                goto out;
 
        error = nfs4_acl_split(acl, dacl);
-       if (error < 0)
+       if (error)
                goto out_acl;
 
-       if (pacl != NULL) {
-               if (acl->naces == 0) {
-                       error = -ENODATA;
-                       goto try_dpacl;
-               }
-
-               *pacl = _nfsv4_to_posix_one(acl, flags);
-               if (IS_ERR(*pacl)) {
-                       error = PTR_ERR(*pacl);
-                       *pacl = NULL;
-                       goto out_acl;
-               }
+       *pacl = _nfsv4_to_posix_one(acl, flags);
+       if (IS_ERR(*pacl)) {
+               error = PTR_ERR(*pacl);
+               *pacl = NULL;
+               goto out_acl;
        }
 
-try_dpacl:
-       if (dpacl != NULL) {
-               if (dacl->naces == 0) {
-                       if (pacl == NULL || *pacl == NULL)
-                               error = -ENODATA;
-                       goto out_acl;
-               }
-
-               error = 0;
-               *dpacl = _nfsv4_to_posix_one(dacl, flags);
-               if (IS_ERR(*dpacl)) {
-                       error = PTR_ERR(*dpacl);
-                       *dpacl = NULL;
-                       goto out_acl;
-               }
+       *dpacl = _nfsv4_to_posix_one(dacl, flags);
+       if (IS_ERR(*dpacl)) {
+               error = PTR_ERR(*dpacl);
+               *dpacl = NULL;
        }
-
 out_acl:
-       if (error && pacl) {
+       if (error) {
                posix_acl_release(*pacl);
                *pacl = NULL;
        }
@@ -429,349 +382,311 @@ out:
        return error;
 }
 
+/*
+ * While processing the NFSv4 ACE, this maintains bitmasks representing
+ * which permission bits have been allowed and which denied to a given
+ * entity: */
+struct posix_ace_state {
+       u32 allow;
+       u32 deny;
+};
+
+struct posix_user_ace_state {
+       uid_t uid;
+       struct posix_ace_state perms;
+};
+
+struct posix_ace_state_array {
+       int n;
+       struct posix_user_ace_state aces[];
+};
+
+/*
+ * While processing the NFSv4 ACE, this maintains the partial permissions
+ * calculated so far: */
+
+struct posix_acl_state {
+       struct posix_ace_state owner;
+       struct posix_ace_state group;
+       struct posix_ace_state other;
+       struct posix_ace_state everyone;
+       struct posix_ace_state mask; /* Deny unused in this case */
+       struct posix_ace_state_array *users;
+       struct posix_ace_state_array *groups;
+};
+
 static int
-same_who(struct nfs4_ace *a, struct nfs4_ace *b)
+init_state(struct posix_acl_state *state, int cnt)
 {
-       return a->whotype == b->whotype &&
-               (a->whotype != NFS4_ACL_WHO_NAMED || a->who == b->who);
+       int alloc;
+
+       memset(state, 0, sizeof(struct posix_acl_state));
+       /*
+        * In the worst case, each individual acl could be for a distinct
+        * named user or group, but we don't no which, so we allocate
+        * enough space for either:
+        */
+       alloc = sizeof(struct posix_ace_state_array)
+               + cnt*sizeof(struct posix_ace_state);
+       state->users = kzalloc(alloc, GFP_KERNEL);
+       if (!state->users)
+               return -ENOMEM;
+       state->groups = kzalloc(alloc, GFP_KERNEL);
+       if (!state->groups) {
+               kfree(state->users);
+               return -ENOMEM;
+       }
+       return 0;
 }
 
-static int
-complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny,
-               unsigned int flags)
-{
-       int ignore = 0;
-       if (!(flags & NFS4_ACL_DIR))
-               ignore |= NFS4_ACE_DELETE_CHILD;
-       return MASK_EQUAL(ignore|deny_mask(allow->access_mask, flags),
-                         ignore|deny->access_mask) &&
-               allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
-               deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
-               allow->flag == deny->flag &&
-               same_who(allow, deny);
+static void
+free_state(struct posix_acl_state *state) {
+       kfree(state->users);
+       kfree(state->groups);
 }
 
-static inline int
-user_obj_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-               struct posix_acl *pacl, struct posix_acl_entry **pace,
-               unsigned int flags)
+static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate)
 {
-       int error = -EINVAL;
-       struct nfs4_ace *ace, *ace2;
-
-       ace = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace == NULL)
-               goto out;
-       if (ace2type(ace) != ACL_USER_OBJ)
-               goto out;
-       error = write_pace(ace, pacl, pace, ACL_USER_OBJ, flags);
-       if (error < 0)
-               goto out;
-       error = -EINVAL;
-       ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace2 == NULL)
-               goto out;
-       if (!complementary_ace_pair(ace, ace2, flags))
-               goto out;
-       error = 0;
-out:
-       return error;
+       state->mask.allow |= astate->allow;
 }
 
-static inline int
-users_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-               struct nfs4_ace **mask_ace,
-               struct posix_acl *pacl, struct posix_acl_entry **pace,
-               unsigned int flags)
-{
-       int error = -EINVAL;
-       struct nfs4_ace *ace, *ace2;
+/*
+ * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
+ * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
+ * to traditional read/write/execute permissions.
+ *
+ * It's problematic to reject acls that use certain mode bits, because it
+ * places the burden on users to learn the rules about which bits one
+ * particular server sets, without giving the user a lot of help--we return an
+ * error that could mean any number of different things.  To make matters
+ * worse, the problematic bits might be introduced by some application that's
+ * automatically mapping from some other acl model.
+ *
+ * So wherever possible we accept anything, possibly erring on the side of
+ * denying more permissions than necessary.
+ *
+ * However we do reject *explicit* DENY's of a few bits representing
+ * permissions we could never deny:
+ */
 
-       ace = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace == NULL)
-               goto out;
-       while (ace2type(ace) == ACL_USER) {
-               if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
-                       goto out;
-               if (*mask_ace &&
-                       !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-                       goto out;
-               *mask_ace = ace;
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
-               if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-                       goto out;
-               error = write_pace(ace, pacl, pace, ACL_USER, flags);
-               if (error < 0)
-                       goto out;
-               error = -EINVAL;
-               ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace2 == NULL)
-                       goto out;
-               if (!complementary_ace_pair(ace, ace2, flags))
-                       goto out;
-               if ((*mask_ace)->flag != ace2->flag ||
-                               !same_who(*mask_ace, ace2))
-                       goto out;
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
-       }
-       error = 0;
-out:
-       return error;
+static inline int check_deny(u32 mask, int isowner)
+{
+       if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
+               return -EINVAL;
+       if (!isowner)
+               return 0;
+       if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
+               return -EINVAL;
+       return 0;
 }
 
-static inline int
-group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-               struct nfs4_ace **mask_ace,
-               struct posix_acl *pacl, struct posix_acl_entry **pace,
-               unsigned int flags)
+static struct posix_acl *
+posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 {
-       int error = -EINVAL;
-       struct nfs4_ace *ace, *ace2;
-       struct ace_container *ac;
-       struct list_head group_l;
-
-       INIT_LIST_HEAD(&group_l);
-       ace = list_entry(*p, struct nfs4_ace, l_ace);
-
-       /* group owner (mask and allow aces) */
+       struct posix_acl_entry *pace;
+       struct posix_acl *pacl;
+       int nace;
+       int i, error = 0;
 
-       if (pacl->a_count != 3) {
-               /* then the group owner should be preceded by mask */
-               if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
-                       goto out;
-               if (*mask_ace &&
-                       !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-                       goto out;
-               *mask_ace = ace;
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
+       nace = 4 + state->users->n + state->groups->n;
+       pacl = posix_acl_alloc(nace, GFP_KERNEL);
+       if (!pacl)
+               return ERR_PTR(-ENOMEM);
 
-               if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace))
-                       goto out;
+       pace = pacl->a_entries;
+       pace->e_tag = ACL_USER_OBJ;
+       error = check_deny(state->owner.deny, 1);
+       if (error)
+               goto out_err;
+       low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
+       pace->e_id = ACL_UNDEFINED_ID;
+
+       for (i=0; i < state->users->n; i++) {
+               pace++;
+               pace->e_tag = ACL_USER;
+               error = check_deny(state->users->aces[i].perms.deny, 0);
+               if (error)
+                       goto out_err;
+               low_mode_from_nfs4(state->users->aces[i].perms.allow,
+                                       &pace->e_perm, flags);
+               pace->e_id = state->users->aces[i].uid;
+               add_to_mask(state, &state->users->aces[i].perms);
        }
 
-       if (ace2type(ace) != ACL_GROUP_OBJ)
-               goto out;
-
-       ac = kmalloc(sizeof(*ac), GFP_KERNEL);
-       error = -ENOMEM;
-       if (ac == NULL)
-               goto out;
-       ac->ace = ace;
-       list_add_tail(&ac->ace_l, &group_l);
-
-       error = -EINVAL;
-       if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-               goto out;
-
-       error = write_pace(ace, pacl, pace, ACL_GROUP_OBJ, flags);
-       if (error < 0)
-               goto out;
-
-       error = -EINVAL;
-       ace = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace == NULL)
-               goto out;
-
-       /* groups (mask and allow aces) */
-
-       while (ace2type(ace) == ACL_GROUP) {
-               if (*mask_ace == NULL)
-                       goto out;
-
-               if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
-                       !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
-                       goto out;
-               *mask_ace = ace;
+       pace++;
+       pace->e_tag = ACL_GROUP_OBJ;
+       error = check_deny(state->group.deny, 0);
+       if (error)
+               goto out_err;
+       low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
+       pace->e_id = ACL_UNDEFINED_ID;
+       add_to_mask(state, &state->group);
+
+       for (i=0; i < state->groups->n; i++) {
+               pace++;
+               pace->e_tag = ACL_GROUP;
+               error = check_deny(state->groups->aces[i].perms.deny, 0);
+               if (error)
+                       goto out_err;
+               low_mode_from_nfs4(state->groups->aces[i].perms.allow,
+                                       &pace->e_perm, flags);
+               pace->e_id = state->groups->aces[i].uid;
+               add_to_mask(state, &state->groups->aces[i].perms);
+       }
 
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
-               ac = kmalloc(sizeof(*ac), GFP_KERNEL);
-               error = -ENOMEM;
-               if (ac == NULL)
-                       goto out;
-               error = -EINVAL;
-               if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
-                               !same_who(ace, *mask_ace))
-                       goto out;
+       pace++;
+       pace->e_tag = ACL_MASK;
+       low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
+       pace->e_id = ACL_UNDEFINED_ID;
 
-               ac->ace = ace;
-               list_add_tail(&ac->ace_l, &group_l);
+       pace++;
+       pace->e_tag = ACL_OTHER;
+       error = check_deny(state->other.deny, 0);
+       if (error)
+               goto out_err;
+       low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
+       pace->e_id = ACL_UNDEFINED_ID;
 
-               error = write_pace(ace, pacl, pace, ACL_GROUP, flags);
-               if (error < 0)
-                       goto out;
-               error = -EINVAL;
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
-       }
+       return pacl;
+out_err:
+       posix_acl_release(pacl);
+       return ERR_PTR(error);
+}
 
-       /* group owner (deny ace) */
+static inline void allow_bits(struct posix_ace_state *astate, u32 mask)
+{
+       /* Allow all bits in the mask not already denied: */
+       astate->allow |= mask & ~astate->deny;
+}
 
-       if (ace2type(ace) != ACL_GROUP_OBJ)
-               goto out;
-       ac = list_entry(group_l.next, struct ace_container, ace_l);
-       ace2 = ac->ace;
-       if (!complementary_ace_pair(ace2, ace, flags))
-               goto out;
-       list_del(group_l.next);
-       kfree(ac);
+static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
+{
+       /* Deny all bits in the mask not already allowed: */
+       astate->deny |= mask & ~astate->allow;
+}
 
-       /* groups (deny aces) */
+static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
+{
+       int i;
 
-       while (!list_empty(&group_l)) {
-               ace = get_next_v4_ace(p, &n4acl->ace_head);
-               if (ace == NULL)
-                       goto out;
-               if (ace2type(ace) != ACL_GROUP)
-                       goto out;
-               ac = list_entry(group_l.next, struct ace_container, ace_l);
-               ace2 = ac->ace;
-               if (!complementary_ace_pair(ace2, ace, flags))
-                       goto out;
-               list_del(group_l.next);
-               kfree(ac);
-       }
+       for (i = 0; i < a->n; i++)
+               if (a->aces[i].uid == uid)
+                       return i;
+       /* Not found: */
+       a->n++;
+       a->aces[i].uid = uid;
+       a->aces[i].perms.allow = state->everyone.allow;
+       a->aces[i].perms.deny  = state->everyone.deny;
 
-       ace = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace == NULL)
-               goto out;
-       if (ace2type(ace) != ACL_OTHER)
-               goto out;
-       error = 0;
-out:
-       while (!list_empty(&group_l)) {
-               ac = list_entry(group_l.next, struct ace_container, ace_l);
-               list_del(group_l.next);
-               kfree(ac);
-       }
-       return error;
+       return i;
 }
 
-static inline int
-mask_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-               struct nfs4_ace **mask_ace,
-               struct posix_acl *pacl, struct posix_acl_entry **pace,
-               unsigned int flags)
+static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
 {
-       int error = -EINVAL;
-       struct nfs4_ace *ace;
+       int i;
 
-       ace = list_entry(*p, struct nfs4_ace, l_ace);
-       if (pacl->a_count != 3) {
-               if (*mask_ace == NULL)
-                       goto out;
-               (*mask_ace)->access_mask = deny_mask((*mask_ace)->access_mask, flags);
-               write_pace(*mask_ace, pacl, pace, ACL_MASK, flags);
-       }
-       error = 0;
-out:
-       return error;
+       for (i=0; i < a->n; i++)
+               deny_bits(&a->aces[i].perms, mask);
 }
 
-static inline int
-other_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
-               struct posix_acl *pacl, struct posix_acl_entry **pace,
-               unsigned int flags)
+static void allow_bits_array(struct posix_ace_state_array *a, u32 mask)
 {
-       int error = -EINVAL;
-       struct nfs4_ace *ace, *ace2;
+       int i;
 
-       ace = list_entry(*p, struct nfs4_ace, l_ace);
-       if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
-               goto out;
-       error = write_pace(ace, pacl, pace, ACL_OTHER, flags);
-       if (error < 0)
-               goto out;
-       error = -EINVAL;
-       ace2 = get_next_v4_ace(p, &n4acl->ace_head);
-       if (ace2 == NULL)
-               goto out;
-       if (!complementary_ace_pair(ace, ace2, flags))
-               goto out;
-       error = 0;
-out:
-       return error;
+       for (i=0; i < a->n; i++)
+               allow_bits(&a->aces[i].perms, mask);
 }
 
-static int
-calculate_posix_ace_count(struct nfs4_acl *n4acl)
+static void process_one_v4_ace(struct posix_acl_state *state,
+                               struct nfs4_ace *ace)
 {
-       if (n4acl->naces == 6) /* owner, owner group, and other only */
-               return 3;
-       else { /* Otherwise there must be a mask entry. */
-               /* Also, the remaining entries are for named users and
-                * groups, and come in threes (mask, allow, deny): */
-               if (n4acl->naces < 7)
-                       return -EINVAL;
-               if ((n4acl->naces - 7) % 3)
-                       return -EINVAL;
-               return 4 + (n4acl->naces - 7)/3;
+       u32 mask = ace->access_mask;
+       int i;
+
+       switch (ace2type(ace)) {
+       case ACL_USER_OBJ:
+               if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+                       allow_bits(&state->owner, mask);
+               } else {
+                       deny_bits(&state->owner, mask);
+               }
+               break;
+       case ACL_USER:
+               i = find_uid(state, state->users, ace->who);
+               if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+                       allow_bits(&state->users->aces[i].perms, mask);
+               } else {
+                       deny_bits(&state->users->aces[i].perms, mask);
+                       mask = state->users->aces[i].perms.deny;
+                       deny_bits(&state->owner, mask);
+               }
+               break;
+       case ACL_GROUP_OBJ:
+               if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+                       allow_bits(&state->group, mask);
+               } else {
+                       deny_bits(&state->group, mask);
+                       mask = state->group.deny;
+                       deny_bits(&state->owner, mask);
+                       deny_bits(&state->everyone, mask);
+                       deny_bits_array(state->users, mask);
+                       deny_bits_array(state->groups, mask);
+               }
+               break;
+       case ACL_GROUP:
+               i = find_uid(state, state->groups, ace->who);
+               if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+                       allow_bits(&state->groups->aces[i].perms, mask);
+               } else {
+                       deny_bits(&state->groups->aces[i].perms, mask);
+                       mask = state->groups->aces[i].perms.deny;
+                       deny_bits(&state->owner, mask);
+                       deny_bits(&state->group, mask);
+                       deny_bits(&state->everyone, mask);
+                       deny_bits_array(state->users, mask);
+                       deny_bits_array(state->groups, mask);
+               }
+               break;
+       case ACL_OTHER:
+               if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
+                       allow_bits(&state->owner, mask);
+                       allow_bits(&state->group, mask);
+                       allow_bits(&state->other, mask);
+                       allow_bits(&state->everyone, mask);
+                       allow_bits_array(state->users, mask);
+                       allow_bits_array(state->groups, mask);
+               } else {
+                       deny_bits(&state->owner, mask);
+                       deny_bits(&state->group, mask);
+                       deny_bits(&state->other, mask);
+                       deny_bits(&state->everyone, mask);
+                       deny_bits_array(state->users, mask);
+                       deny_bits_array(state->groups, mask);
+               }
        }
 }
 
-
 static struct posix_acl *
 _nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags)
 {
+       struct posix_acl_state state;
        struct posix_acl *pacl;
-       int error = -EINVAL, nace = 0;
-       struct list_head *p;
-       struct nfs4_ace *mask_ace = NULL;
-       struct posix_acl_entry *pace;
-
-       nace = calculate_posix_ace_count(n4acl);
-       if (nace < 0)
-               goto out_err;
-
-       pacl = posix_acl_alloc(nace, GFP_KERNEL);
-       error = -ENOMEM;
-       if (pacl == NULL)
-               goto out_err;
-
-       pace = &pacl->a_entries[0];
-       p = &n4acl->ace_head;
-
-       error = user_obj_from_v4(n4acl, &p, pacl, &pace, flags);
-       if (error)
-               goto out_acl;
-
-       error = users_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
-       if (error)
-               goto out_acl;
+       struct nfs4_ace *ace;
+       int ret;
 
-       error = group_obj_and_groups_from_v4(n4acl, &p, &mask_ace, pacl, &pace,
-                                               flags);
-       if (error)
-               goto out_acl;
+       ret = init_state(&state, n4acl->naces);
+       if (ret)
+               return ERR_PTR(ret);
 
-       error = mask_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
-       if (error)
-               goto out_acl;
-       error = other_from_v4(n4acl, &p, pacl, &pace, flags);
-       if (error)
-               goto out_acl;
+       list_for_each_entry(ace, &n4acl->ace_head, l_ace)
+               process_one_v4_ace(&state, ace);
 
-       error = -EINVAL;
-       if (p->next != &n4acl->ace_head)
-               goto out_acl;
-       if (pace != pacl->a_entries + pacl->a_count)
-               goto out_acl;
+       pacl = posix_state_to_acl(&state, flags);
 
-       sort_pacl(pacl);
+       free_state(&state);
 
-       return pacl;
-out_acl:
-       posix_acl_release(pacl);
-out_err:
-       pacl = ERR_PTR(error);
+       if (!IS_ERR(pacl))
+               sort_pacl(pacl);
        return pacl;
 }
 
@@ -785,22 +700,41 @@ nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
        list_for_each_safe(h, n, &acl->ace_head) {
                ace = list_entry(h, struct nfs4_ace, l_ace);
 
-               if ((ace->flag & NFS4_INHERITANCE_FLAGS)
-                               != NFS4_INHERITANCE_FLAGS)
-                       continue;
+               if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
+                   ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
+                       return -EINVAL;
 
-               error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
-                               ace->access_mask, ace->whotype, ace->who);
-               if (error < 0)
-                       goto out;
+               if (ace->flag & ~NFS4_SUPPORTED_FLAGS)
+                       return -EINVAL;
 
-               list_del(h);
-               kfree(ace);
-               acl->naces--;
+               switch (ace->flag & NFS4_INHERITANCE_FLAGS) {
+               case 0:
+                       /* Leave this ace in the effective acl: */
+                       continue;
+               case NFS4_INHERITANCE_FLAGS:
+                       /* Add this ace to the default acl and remove it
+                        * from the effective acl: */
+                       error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
+                               ace->access_mask, ace->whotype, ace->who);
+                       if (error)
+                               return error;
+                       list_del(h);
+                       kfree(ace);
+                       acl->naces--;
+                       break;
+               case NFS4_INHERITANCE_FLAGS & ~NFS4_ACE_INHERIT_ONLY_ACE:
+                       /* Add this ace to the default, but leave it in
+                        * the effective acl as well: */
+                       error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
+                               ace->access_mask, ace->whotype, ace->who);
+                       if (error)
+                               return error;
+                       break;
+               default:
+                       return -EINVAL;
+               }
        }
-
-out:
-       return error;
+       return 0;
 }
 
 static short
@@ -930,23 +864,6 @@ nfs4_acl_write_who(int who, char *p)
        return -1;
 }
 
-static inline int
-match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
-{
-       switch (ace->whotype) {
-               case NFS4_ACL_WHO_NAMED:
-                       return who == ace->who;
-               case NFS4_ACL_WHO_OWNER:
-                       return who == owner;
-               case NFS4_ACL_WHO_GROUP:
-                       return who == group;
-               case NFS4_ACL_WHO_EVERYONE:
-                       return 1;
-               default:
-                       return 0;
-       }
-}
-
 EXPORT_SYMBOL(nfs4_acl_new);
 EXPORT_SYMBOL(nfs4_acl_free);
 EXPORT_SYMBOL(nfs4_acl_add_ace);
index 15ded7a30a72dcf4426b0e45c13c6a45395f6505..8333db12caca56207a0142fcb9a94000f962ad69 100644 (file)
@@ -646,7 +646,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
        *p++ = nfssvc_boot.tv_usec;
 
        status =  nfsd_write(rqstp, current_fh, filp, write->wr_offset,
-                       write->wr_vec, write->wr_vlen, write->wr_buflen,
+                       rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
                        &write->wr_how_written);
        if (filp)
                fput(filp);
@@ -802,13 +802,29 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
                * require a valid current filehandle
                */
-               if ((!current_fh->fh_dentry) &&
-                  !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) ||
-                  (op->opnum == OP_SETCLIENTID) ||
-                  (op->opnum == OP_SETCLIENTID_CONFIRM) ||
-                  (op->opnum == OP_RENEW) || (op->opnum == OP_RESTOREFH) ||
-                  (op->opnum == OP_RELEASE_LOCKOWNER))) {
-                       op->status = nfserr_nofilehandle;
+               if (!current_fh->fh_dentry) {
+                       if (!((op->opnum == OP_PUTFH) ||
+                             (op->opnum == OP_PUTROOTFH) ||
+                             (op->opnum == OP_SETCLIENTID) ||
+                             (op->opnum == OP_SETCLIENTID_CONFIRM) ||
+                             (op->opnum == OP_RENEW) ||
+                             (op->opnum == OP_RESTOREFH) ||
+                             (op->opnum == OP_RELEASE_LOCKOWNER))) {
+                               op->status = nfserr_nofilehandle;
+                               goto encode_op;
+                       }
+               }
+               /* Check must be done at start of each operation, except
+                * for GETATTR and ops not listed as returning NFS4ERR_MOVED
+                */
+               else if (current_fh->fh_export->ex_fslocs.migrated &&
+                        !((op->opnum == OP_GETATTR) ||
+                          (op->opnum == OP_PUTROOTFH) ||
+                          (op->opnum == OP_PUTPUBFH) ||
+                          (op->opnum == OP_RENEW) ||
+                          (op->opnum == OP_SETCLIENTID) ||
+                          (op->opnum == OP_RELEASE_LOCKOWNER))) {
+                       op->status = nfserr_moved;
                        goto encode_op;
                }
                switch (op->opnum) {
index 5446a0861d1d728ea12ee0e1faf2a52b2a19672b..41fc241b729aa2a3ad78e0c91f25b751cd3cad0e 100644 (file)
 
 #define NFSDDBG_FACILITY               NFSDDBG_XDR
 
+/*
+ * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
+ * directory in order to indicate to the client that a filesystem boundary is present
+ * We use a fixed fsid for a referral
+ */
+#define NFS4_REFERRAL_FSID_MAJOR       0x8000000ULL
+#define NFS4_REFERRAL_FSID_MINOR       0x8000000ULL
+
 static int
 check_filename(char *str, int len, int err)
 {
@@ -198,8 +206,7 @@ static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
                p = new;
                memcpy(p, argp->tmp, nbytes);
        } else {
-               if (p != argp->tmpp)
-                       BUG();
+               BUG_ON(p != argp->tmpp);
                argp->tmpp = NULL;
        }
        if (defer_free(argp, kfree, p)) {
@@ -927,26 +934,26 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
                printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); 
                goto xdr_error;
        }
-       write->wr_vec[0].iov_base = p;
-       write->wr_vec[0].iov_len = avail;
+       argp->rqstp->rq_vec[0].iov_base = p;
+       argp->rqstp->rq_vec[0].iov_len = avail;
        v = 0;
        len = write->wr_buflen;
-       while (len > write->wr_vec[v].iov_len) {
-               len -= write->wr_vec[v].iov_len;
+       while (len > argp->rqstp->rq_vec[v].iov_len) {
+               len -= argp->rqstp->rq_vec[v].iov_len;
                v++;
-               write->wr_vec[v].iov_base = page_address(argp->pagelist[0]);
+               argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
                argp->pagelist++;
                if (argp->pagelen >= PAGE_SIZE) {
-                       write->wr_vec[v].iov_len = PAGE_SIZE;
+                       argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
                        argp->pagelen -= PAGE_SIZE;
                } else {
-                       write->wr_vec[v].iov_len = argp->pagelen;
+                       argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
                        argp->pagelen -= len;
                }
        }
-       argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len);
-       argp->p = (u32*)  (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
-       write->wr_vec[v].iov_len = len;
+       argp->end = (u32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
+       argp->p = (u32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
+       argp->rqstp->rq_vec[v].iov_len = len;
        write->wr_vlen = v+1;
 
        DECODE_TAIL;
@@ -1224,6 +1231,119 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                        stateowner->so_replay.rp_buflen);       \
        } } while (0);
 
+/* Encode as an array of strings the string given with components
+ * seperated @sep.
+ */
+static int nfsd4_encode_components(char sep, char *components,
+                                  u32 **pp, int *buflen)
+{
+       u32 *p = *pp;
+       u32 *countp = p;
+       int strlen, count=0;
+       char *str, *end;
+
+       dprintk("nfsd4_encode_components(%s)\n", components);
+       if ((*buflen -= 4) < 0)
+               return nfserr_resource;
+       WRITE32(0); /* We will fill this in with @count later */
+       end = str = components;
+       while (*end) {
+               for (; *end && (*end != sep); end++)
+                       ; /* Point to end of component */
+               strlen = end - str;
+               if (strlen) {
+                       if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
+                               return nfserr_resource;
+                       WRITE32(strlen);
+                       WRITEMEM(str, strlen);
+                       count++;
+               }
+               else
+                       end++;
+               str = end;
+       }
+       *pp = p;
+       p = countp;
+       WRITE32(count);
+       return 0;
+}
+
+/*
+ * encode a location element of a fs_locations structure
+ */
+static int nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
+                                   u32 **pp, int *buflen)
+{
+       int status;
+       u32 *p = *pp;
+
+       status = nfsd4_encode_components(':', location->hosts, &p, buflen);
+       if (status)
+               return status;
+       status = nfsd4_encode_components('/', location->path, &p, buflen);
+       if (status)
+               return status;
+       *pp = p;
+       return 0;
+}
+
+/*
+ * Return the path to an export point in the pseudo filesystem namespace
+ * Returned string is safe to use as long as the caller holds a reference
+ * to @exp.
+ */
+static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp)
+{
+       struct svc_fh tmp_fh;
+       char *path, *rootpath;
+       int stat;
+
+       fh_init(&tmp_fh, NFS4_FHSIZE);
+       stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle);
+       if (stat)
+               return ERR_PTR(stat);
+       rootpath = tmp_fh.fh_export->ex_path;
+
+       path = exp->ex_path;
+
+       if (strncmp(path, rootpath, strlen(rootpath))) {
+               printk("nfsd: fs_locations failed;"
+                       "%s is not contained in %s\n", path, rootpath);
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+
+       return path + strlen(rootpath);
+}
+
+/*
+ *  encode a fs_locations structure
+ */
+static int nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
+                                    struct svc_export *exp,
+                                    u32 **pp, int *buflen)
+{
+       int status, i;
+       u32 *p = *pp;
+       struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
+       char *root = nfsd4_path(rqstp, exp);
+
+       if (IS_ERR(root))
+               return PTR_ERR(root);
+       status = nfsd4_encode_components('/', root, &p, buflen);
+       if (status)
+               return status;
+       if ((*buflen -= 4) < 0)
+               return nfserr_resource;
+       WRITE32(fslocs->locations_count);
+       for (i=0; i<fslocs->locations_count; i++) {
+               status = nfsd4_encode_fs_location4(&fslocs->locations[i],
+                                                  &p, buflen);
+               if (status)
+                       return status;
+       }
+       *pp = p;
+       return 0;
+}
 
 static u32 nfs4_ftypes[16] = {
         NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
@@ -1273,6 +1393,25 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
        return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
 }
 
+#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
+                             FATTR4_WORD0_RDATTR_ERROR)
+#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
+
+static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
+{
+       /* As per referral draft:  */
+       if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
+           *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
+               if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
+                   *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
+                       *rdattr_err = NFSERR_MOVED;
+               else
+                       return nfserr_moved;
+       }
+       *bmval0 &= WORD0_ABSENT_FS_ATTRS;
+       *bmval1 &= WORD1_ABSENT_FS_ATTRS;
+       return 0;
+}
 
 /*
  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
@@ -1295,6 +1434,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        u32 *attrlenp;
        u32 dummy;
        u64 dummy64;
+       u32 rdattr_err = 0;
        u32 *p = buffer;
        int status;
        int aclsupport = 0;
@@ -1304,6 +1444,12 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
        BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
 
+       if (exp->ex_fslocs.migrated) {
+               status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
+               if (status)
+                       goto out;
+       }
+
        status = vfs_getattr(exp->ex_mnt, dentry, &stat);
        if (status)
                goto out_nfserr;
@@ -1335,6 +1481,11 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                                goto out_nfserr;
                }
        }
+       if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
+               if (exp->ex_fslocs.locations == NULL) {
+                       bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS;
+               }
+       }
        if ((buflen -= 16) < 0)
                goto out_resource;
 
@@ -1344,12 +1495,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        attrlenp = p++;                /* to be backfilled later */
 
        if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
+               u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
                if ((buflen -= 12) < 0)
                        goto out_resource;
+               if (!aclsupport)
+                       word0 &= ~FATTR4_WORD0_ACL;
+               if (!exp->ex_fslocs.locations)
+                       word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
                WRITE32(2);
-               WRITE32(aclsupport ?
-                       NFSD_SUPPORTED_ATTRS_WORD0 :
-                       NFSD_SUPPORTED_ATTRS_WORD0 & ~FATTR4_WORD0_ACL);
+               WRITE32(word0);
                WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
        }
        if (bmval0 & FATTR4_WORD0_TYPE) {
@@ -1403,7 +1557,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        if (bmval0 & FATTR4_WORD0_FSID) {
                if ((buflen -= 16) < 0)
                        goto out_resource;
-               if (is_fsid(fhp, rqstp->rq_reffh)) {
+               if (exp->ex_fslocs.migrated) {
+                       WRITE64(NFS4_REFERRAL_FSID_MAJOR);
+                       WRITE64(NFS4_REFERRAL_FSID_MINOR);
+               } else if (is_fsid(fhp, rqstp->rq_reffh)) {
                        WRITE64((u64)exp->ex_fsid);
                        WRITE64((u64)0);
                } else {
@@ -1426,7 +1583,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
                if ((buflen -= 4) < 0)
                        goto out_resource;
-               WRITE32(0);
+               WRITE32(rdattr_err);
        }
        if (bmval0 & FATTR4_WORD0_ACL) {
                struct nfs4_ace *ace;
@@ -1514,6 +1671,13 @@ out_acl:
                        goto out_resource;
                WRITE64((u64) statfs.f_files);
        }
+       if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
+               status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
+               if (status == nfserr_resource)
+                       goto out_resource;
+               if (status)
+                       goto out;
+       }
        if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
                if ((buflen -= 4) < 0)
                        goto out_resource;
@@ -1537,12 +1701,12 @@ out_acl:
        if (bmval0 & FATTR4_WORD0_MAXREAD) {
                if ((buflen -= 8) < 0)
                        goto out_resource;
-               WRITE64((u64) NFSSVC_MAXBLKSIZE);
+               WRITE64((u64) svc_max_payload(rqstp));
        }
        if (bmval0 & FATTR4_WORD0_MAXWRITE) {
                if ((buflen -= 8) < 0)
                        goto out_resource;
-               WRITE64((u64) NFSSVC_MAXBLKSIZE);
+               WRITE64((u64) svc_max_payload(rqstp));
        }
        if (bmval1 & FATTR4_WORD1_MODE) {
                if ((buflen -= 4) < 0)
@@ -1846,7 +2010,6 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge
        nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
                                    resp->p, &buflen, getattr->ga_bmval,
                                    resp->rqstp);
-
        if (!nfserr)
                resp->p += buflen;
        return nfserr;
@@ -2040,7 +2203,8 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n
 }
 
 static int
-nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
+nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
+                 struct nfsd4_read *read)
 {
        u32 eof;
        int v, pn;
@@ -2055,31 +2219,33 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
 
        RESERVE_SPACE(8); /* eof flag and byte count */
 
-       maxcount = NFSSVC_MAXBLKSIZE;
+       maxcount = svc_max_payload(resp->rqstp);
        if (maxcount > read->rd_length)
                maxcount = read->rd_length;
 
        len = maxcount;
        v = 0;
        while (len > 0) {
-               pn = resp->rqstp->rq_resused;
-               svc_take_page(resp->rqstp);
-               read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]);
-               read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE;
+               pn = resp->rqstp->rq_resused++;
+               resp->rqstp->rq_vec[v].iov_base =
+                       page_address(resp->rqstp->rq_respages[pn]);
+               resp->rqstp->rq_vec[v].iov_len =
+                       len < PAGE_SIZE ? len : PAGE_SIZE;
                v++;
                len -= PAGE_SIZE;
        }
        read->rd_vlen = v;
 
        nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,
-                       read->rd_offset, read->rd_iov, read->rd_vlen,
+                       read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
                        &maxcount);
 
        if (nfserr == nfserr_symlink)
                nfserr = nfserr_inval;
        if (nfserr)
                return nfserr;
-       eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size);
+       eof = (read->rd_offset + maxcount >=
+              read->rd_fhp->fh_dentry->d_inode->i_size);
 
        WRITE32(eof);
        WRITE32(maxcount);
@@ -2089,7 +2255,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
        resp->xbuf->page_len = maxcount;
 
        /* Use rest of head for padding and remaining ops: */
-       resp->rqstp->rq_restailpage = 0;
        resp->xbuf->tail[0].iov_base = p;
        resp->xbuf->tail[0].iov_len = 0;
        if (maxcount&3) {
@@ -2114,8 +2279,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
        if (resp->xbuf->page_len)
                return nfserr_resource;
 
-       svc_take_page(resp->rqstp);
-       page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+       page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
 
        maxcount = PAGE_SIZE;
        RESERVE_SPACE(4);
@@ -2139,7 +2303,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
        resp->xbuf->page_len = maxcount;
 
        /* Use rest of head for padding and remaining ops: */
-       resp->rqstp->rq_restailpage = 0;
        resp->xbuf->tail[0].iov_base = p;
        resp->xbuf->tail[0].iov_len = 0;
        if (maxcount&3) {
@@ -2190,8 +2353,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
                goto err_no_verf;
        }
 
-       svc_take_page(resp->rqstp);
-       page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+       page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
        readdir->common.err = 0;
        readdir->buflen = maxcount;
        readdir->buffer = page;
@@ -2216,10 +2378,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
        p = readdir->buffer;
        *p++ = 0;       /* no more entries */
        *p++ = htonl(readdir->common.err == nfserr_eof);
-       resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
+       resp->xbuf->page_len = ((char*)p) - (char*)page_address(
+               resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
 
        /* Use rest of head for padding and remaining ops: */
-       resp->rqstp->rq_restailpage = 0;
        resp->xbuf->tail[0].iov_base = tailbase;
        resp->xbuf->tail[0].iov_len = 0;
        resp->p = resp->xbuf->tail[0].iov_base;
index 5c6a477c20ec30693267f0425a4117e1f93caef5..39aed901514b0c34d30cb468b1a8aabadc33b2e8 100644 (file)
@@ -57,6 +57,7 @@ enum {
        NFSD_Pool_Threads,
        NFSD_Versions,
        NFSD_Ports,
+       NFSD_MaxBlkSize,
        /*
         * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
         * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
@@ -82,6 +83,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_versions(struct file *file, char *buf, size_t size);
 static ssize_t write_ports(struct file *file, char *buf, size_t size);
+static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
 #ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
@@ -100,6 +102,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Pool_Threads] = write_pool_threads,
        [NFSD_Versions] = write_versions,
        [NFSD_Ports] = write_ports,
+       [NFSD_MaxBlkSize] = write_maxblksize,
 #ifdef CONFIG_NFSD_V4
        [NFSD_Leasetime] = write_leasetime,
        [NFSD_RecoveryDir] = write_recoverydir,
@@ -523,18 +526,20 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
                err = nfsd_create_serv();
                if (!err) {
                        int proto = 0;
-                       err = lockd_up(proto);
-                       if (!err) {
-                               err = svc_addsock(nfsd_serv, fd, buf, &proto);
-                               if (err)
-                                       lockd_down();
+                       err = svc_addsock(nfsd_serv, fd, buf, &proto);
+                       if (err >= 0) {
+                               err = lockd_up(proto);
+                               if (err < 0)
+                                       svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf);
                        }
                        /* Decrease the count, but don't shutdown the
                         * the service
                         */
+                       lock_kernel();
                        nfsd_serv->sv_nrthreads--;
+                       unlock_kernel();
                }
-               return err;
+               return err < 0 ? err : 0;
        }
        if (buf[0] == '-') {
                char *toclose = kstrdup(buf+1, GFP_KERNEL);
@@ -545,12 +550,43 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
                if (nfsd_serv)
                        len = svc_sock_names(buf, nfsd_serv, toclose);
                unlock_kernel();
+               if (len >= 0)
+                       lockd_down();
                kfree(toclose);
                return len;
        }
        return -EINVAL;
 }
 
+int nfsd_max_blksize;
+
+static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
+{
+       char *mesg = buf;
+       if (size > 0) {
+               int bsize;
+               int rv = get_int(&mesg, &bsize);
+               if (rv)
+                       return rv;
+               /* force bsize into allowed range and
+                * required alignment.
+                */
+               if (bsize < 1024)
+                       bsize = 1024;
+               if (bsize > NFSSVC_MAXBLKSIZE)
+                       bsize = NFSSVC_MAXBLKSIZE;
+               bsize &= ~(1024-1);
+               lock_kernel();
+               if (nfsd_serv && nfsd_serv->sv_nrthreads) {
+                       unlock_kernel();
+                       return -EBUSY;
+               }
+               nfsd_max_blksize = bsize;
+               unlock_kernel();
+       }
+       return sprintf(buf, "%d\n", nfsd_max_blksize);
+}
+
 #ifdef CONFIG_NFSD_V4
 extern time_t nfs4_leasetime(void);
 
@@ -616,6 +652,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
+               [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
 #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
index 06cd0db0f32b306dd34dbf1462fdd74b63ecf38f..9ee1dab5d44adc09214469af2014735f132c50cc 100644 (file)
@@ -146,20 +146,20 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
         * status, 17 words for fattr, and 1 word for the byte count.
         */
 
-       if (NFSSVC_MAXBLKSIZE < argp->count) {
+       if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
                printk(KERN_NOTICE
                        "oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
                                NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
                                ntohs(rqstp->rq_addr.sin_port),
                                argp->count);
-               argp->count = NFSSVC_MAXBLKSIZE;
+               argp->count = NFSSVC_MAXBLKSIZE_V2;
        }
        svc_reserve(rqstp, (19<<2) + argp->count + 4);
 
        resp->count = argp->count;
        nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
                                  argp->offset,
-                                 argp->vec, argp->vlen,
+                                 rqstp->rq_vec, argp->vlen,
                                  &resp->count);
 
        if (nfserr) return nfserr;
@@ -185,7 +185,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
 
        nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
                                   argp->offset,
-                                  argp->vec, argp->vlen,
+                                  rqstp->rq_vec, argp->vlen,
                                   argp->len,
                                   &stable);
        return nfsd_return_attrs(nfserr, resp);
@@ -225,7 +225,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
        nfserr = nfserr_exist;
        if (isdotent(argp->name, argp->len))
                goto done;
-       fh_lock(dirfhp);
+       fh_lock_nested(dirfhp, I_MUTEX_PARENT);
        dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
        if (IS_ERR(dchild)) {
                nfserr = nfserrno(PTR_ERR(dchild));
@@ -553,7 +553,7 @@ static struct svc_procedure         nfsd_procedures2[18] = {
   PROC(none,    void,          void,           none,           RC_NOCACHE, ST),
   PROC(lookup,  diropargs,     diropres,       fhandle,        RC_NOCACHE, ST+FH+AT),
   PROC(readlink, readlinkargs, readlinkres,    none,           RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
-  PROC(read,    readargs,      readres,        fhandle,        RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4),
+  PROC(read,    readargs,      readres,        fhandle,        RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4),
   PROC(none,    void,          void,           none,           RC_NOCACHE, ST),
   PROC(write,   writeargs,     attrstat,       fhandle,        RC_REPLBUFF, ST+AT),
   PROC(create,  createargs,    diropres,       fhandle,        RC_REPLBUFF, ST+FH+AT),
index 19443056ec301a94df4db864d617fac80a0f0fa5..6fa6340a5fb892e217e180218d3199bc4e4b3e55 100644 (file)
@@ -198,9 +198,26 @@ int nfsd_create_serv(void)
                unlock_kernel();
                return 0;
        }
+       if (nfsd_max_blksize == 0) {
+               /* choose a suitable default */
+               struct sysinfo i;
+               si_meminfo(&i);
+               /* Aim for 1/4096 of memory per thread
+                * This gives 1MB on 4Gig machines
+                * But only uses 32K on 128M machines.
+                * Bottom out at 8K on 32M and smaller.
+                * Of course, this is only a default.
+                */
+               nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
+               i.totalram <<= PAGE_SHIFT - 12;
+               while (nfsd_max_blksize > i.totalram &&
+                      nfsd_max_blksize >= 8*1024*2)
+                       nfsd_max_blksize /= 2;
+       }
 
        atomic_set(&nfsd_busy, 0);
-       nfsd_serv = svc_create_pooled(&nfsd_program, NFSD_BUFSIZE,
+       nfsd_serv = svc_create_pooled(&nfsd_program,
+                                     NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize,
                                      nfsd_last_thread,
                                      nfsd, SIG_NOCLEAN, THIS_MODULE);
        if (nfsd_serv == NULL)
index e3a0797dd56ba16ef65fb2df1c348f4ae7e806e2..1135c0d145574a7feb8fdb70c4a19cfd40c7dad1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nfsd/xdr.c
+ * linux/fs/nfsd/nfsxdr.c
  *
  * XDR support for nfsd
  *
@@ -254,19 +254,18 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
        len = args->count     = ntohl(*p++);
        p++; /* totalcount - unused */
 
-       if (len > NFSSVC_MAXBLKSIZE)
-               len = NFSSVC_MAXBLKSIZE;
+       if (len > NFSSVC_MAXBLKSIZE_V2)
+               len = NFSSVC_MAXBLKSIZE_V2;
 
        /* set up somewhere to store response.
         * We take pages, put them on reslist and include in iovec
         */
        v=0;
        while (len > 0) {
-               pn=rqstp->rq_resused;
-               svc_take_page(rqstp);
-               args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
-               args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
-               len -= args->vec[v].iov_len;
+               pn = rqstp->rq_resused++;
+               rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
+               rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
+               len -= rqstp->rq_vec[v].iov_len;
                v++;
        }
        args->vlen = v;
@@ -286,21 +285,21 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
        args->offset = ntohl(*p++);     /* offset */
        p++;                            /* totalcount */
        len = args->len = ntohl(*p++);
-       args->vec[0].iov_base = (void*)p;
-       args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
+       rqstp->rq_vec[0].iov_base = (void*)p;
+       rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
                                (((void*)p) - rqstp->rq_arg.head[0].iov_base);
-       if (len > NFSSVC_MAXBLKSIZE)
-               len = NFSSVC_MAXBLKSIZE;
+       if (len > NFSSVC_MAXBLKSIZE_V2)
+               len = NFSSVC_MAXBLKSIZE_V2;
        v = 0;
-       while (len > args->vec[v].iov_len) {
-               len -= args->vec[v].iov_len;
+       while (len > rqstp->rq_vec[v].iov_len) {
+               len -= rqstp->rq_vec[v].iov_len;
                v++;
-               args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
-               args->vec[v].iov_len = PAGE_SIZE;
+               rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
+               rqstp->rq_vec[v].iov_len = PAGE_SIZE;
        }
-       args->vec[v].iov_len = len;
+       rqstp->rq_vec[v].iov_len = len;
        args->vlen = v+1;
-       return args->vec[0].iov_len > 0;
+       return rqstp->rq_vec[0].iov_len > 0;
 }
 
 int
@@ -333,8 +332,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinka
 {
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
-       svc_take_page(rqstp);
-       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
        return xdr_argsize_check(rqstp, p);
 }
@@ -375,8 +373,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
        if (args->count > PAGE_SIZE)
                args->count = PAGE_SIZE;
 
-       svc_take_page(rqstp);
-       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]);
+       args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]);
 
        return xdr_argsize_check(rqstp, p);
 }
@@ -416,7 +413,6 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
        rqstp->rq_res.page_len = resp->len;
        if (resp->len & 3) {
                /* need to pad the tail */
-               rqstp->rq_restailpage = 0;
                rqstp->rq_res.tail[0].iov_base = p;
                *p = 0;
                rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
@@ -436,7 +432,6 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
        rqstp->rq_res.page_len = resp->count;
        if (resp->count & 3) {
                /* need to pad the tail */
-               rqstp->rq_restailpage = 0;
                rqstp->rq_res.tail[0].iov_base = p;
                *p = 0;
                rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
@@ -463,7 +458,7 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
 {
        struct kstatfs  *stat = &resp->stats;
 
-       *p++ = htonl(NFSSVC_MAXBLKSIZE);        /* max transfer size */
+       *p++ = htonl(NFSSVC_MAXBLKSIZE_V2);     /* max transfer size */
        *p++ = htonl(stat->f_bsize);
        *p++ = htonl(stat->f_blocks);
        *p++ = htonl(stat->f_bfree);
index 443ebc52e38240062e4f3c4d726c8ac4fce740a9..1141bd29e4e3ee3b6f3b9711ace4d7323e42bd5d 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/nfsd_idmap.h>
 #include <linux/security.h>
 #endif /* CONFIG_NFSD_V4 */
+#include <linux/jhash.h>
 
 #include <asm/uaccess.h>
 
@@ -81,10 +82,19 @@ struct raparms {
        dev_t                   p_dev;
        int                     p_set;
        struct file_ra_state    p_ra;
+       unsigned int            p_hindex;
 };
 
+struct raparm_hbucket {
+       struct raparms          *pb_head;
+       spinlock_t              pb_lock;
+} ____cacheline_aligned_in_smp;
+
 static struct raparms *                raparml;
-static struct raparms *                raparm_cache;
+#define RAPARM_HASH_BITS       4
+#define RAPARM_HASH_SIZE       (1<<RAPARM_HASH_BITS)
+#define RAPARM_HASH_MASK       (RAPARM_HASH_SIZE-1)
+static struct raparm_hbucket   raparm_hash[RAPARM_HASH_SIZE];
 
 /* 
  * Called from nfsd_lookup and encode_dirent. Check if we have crossed 
@@ -437,13 +447,11 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
        } else if (error < 0)
                goto out_nfserr;
 
-       if (pacl) {
-               error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
-               if (error < 0)
-                       goto out_nfserr;
-       }
+       error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
+       if (error < 0)
+               goto out_nfserr;
 
-       if (dpacl) {
+       if (S_ISDIR(inode->i_mode)) {
                error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
                if (error < 0)
                        goto out_nfserr;
@@ -743,16 +751,20 @@ nfsd_sync_dir(struct dentry *dp)
  * Obtain the readahead parameters for the file
  * specified by (dev, ino).
  */
-static DEFINE_SPINLOCK(ra_lock);
 
 static inline struct raparms *
 nfsd_get_raparms(dev_t dev, ino_t ino)
 {
        struct raparms  *ra, **rap, **frap = NULL;
        int depth = 0;
+       unsigned int hash;
+       struct raparm_hbucket *rab;
 
-       spin_lock(&ra_lock);
-       for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) {
+       hash = jhash_2words(dev, ino, 0xfeedbeef) & RAPARM_HASH_MASK;
+       rab = &raparm_hash[hash];
+
+       spin_lock(&rab->pb_lock);
+       for (rap = &rab->pb_head; (ra = *rap); rap = &ra->p_next) {
                if (ra->p_ino == ino && ra->p_dev == dev)
                        goto found;
                depth++;
@@ -761,7 +773,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
        }
        depth = nfsdstats.ra_size*11/10;
        if (!frap) {    
-               spin_unlock(&ra_lock);
+               spin_unlock(&rab->pb_lock);
                return NULL;
        }
        rap = frap;
@@ -769,15 +781,16 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
        ra->p_dev = dev;
        ra->p_ino = ino;
        ra->p_set = 0;
+       ra->p_hindex = hash;
 found:
-       if (rap != &raparm_cache) {
+       if (rap != &rab->pb_head) {
                *rap = ra->p_next;
-               ra->p_next   = raparm_cache;
-               raparm_cache = ra;
+               ra->p_next   = rab->pb_head;
+               rab->pb_head = ra;
        }
        ra->p_count++;
        nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
-       spin_unlock(&ra_lock);
+       spin_unlock(&rab->pb_lock);
        return ra;
 }
 
@@ -791,22 +804,26 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
 {
        unsigned long count = desc->count;
        struct svc_rqst *rqstp = desc->arg.data;
+       struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
 
        if (size > count)
                size = count;
 
        if (rqstp->rq_res.page_len == 0) {
                get_page(page);
-               rqstp->rq_respages[rqstp->rq_resused++] = page;
+               put_page(*pp);
+               *pp = page;
+               rqstp->rq_resused++;
                rqstp->rq_res.page_base = offset;
                rqstp->rq_res.page_len = size;
-       } else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
+       } else if (page != pp[-1]) {
                get_page(page);
-               rqstp->rq_respages[rqstp->rq_resused++] = page;
+               put_page(*pp);
+               *pp = page;
+               rqstp->rq_resused++;
                rqstp->rq_res.page_len += size;
-       } else {
+       } else
                rqstp->rq_res.page_len += size;
-       }
 
        desc->count = count - size;
        desc->written += size;
@@ -837,7 +854,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                file->f_ra = ra->p_ra;
 
        if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
-               svc_pushback_unused_pages(rqstp);
+               rqstp->rq_resused = 1;
                err = file->f_op->sendfile(file, &offset, *count,
                                                 nfsd_read_actor, rqstp);
        } else {
@@ -849,11 +866,12 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        /* Write back readahead params */
        if (ra) {
-               spin_lock(&ra_lock);
+               struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
+               spin_lock(&rab->pb_lock);
                ra->p_ra = file->f_ra;
                ra->p_set = 1;
                ra->p_count--;
-               spin_unlock(&ra_lock);
+               spin_unlock(&rab->pb_lock);
        }
 
        if (err >= 0) {
@@ -1829,11 +1847,11 @@ nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
 void
 nfsd_racache_shutdown(void)
 {
-       if (!raparm_cache)
+       if (!raparml)
                return;
        dprintk("nfsd: freeing readahead buffers.\n");
        kfree(raparml);
-       raparm_cache = raparml = NULL;
+       raparml = NULL;
 }
 /*
  * Initialize readahead param cache
@@ -1842,19 +1860,31 @@ int
 nfsd_racache_init(int cache_size)
 {
        int     i;
+       int     j = 0;
+       int     nperbucket;
+
 
-       if (raparm_cache)
+       if (raparml)
                return 0;
+       if (cache_size < 2*RAPARM_HASH_SIZE)
+               cache_size = 2*RAPARM_HASH_SIZE;
        raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL);
 
        if (raparml != NULL) {
                dprintk("nfsd: allocating %d readahead buffers.\n",
                        cache_size);
+               for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) {
+                       raparm_hash[i].pb_head = NULL;
+                       spin_lock_init(&raparm_hash[i].pb_lock);
+               }
+               nperbucket = cache_size >> RAPARM_HASH_BITS;
                memset(raparml, 0, sizeof(struct raparms) * cache_size);
                for (i = 0; i < cache_size - 1; i++) {
-                       raparml[i].p_next = raparml + i + 1;
+                       if (i % nperbucket == 0)
+                               raparm_hash[j++].pb_head = raparml + i;
+                       if (i % nperbucket < nperbucket-1)
+                               raparml[i].p_next = raparml + i + 1;
                }
-               raparm_cache = raparml;
        } else {
                printk(KERN_WARNING
                       "nfsd: Could not allocate memory read-ahead cache.\n");
index b83381c07ad6390c962cdf30f30c9c7de0157287..6993faea28acfab649e9b868814e64031d83883c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_ascii.c
+ * linux/fs/nls/nls_ascii.c
  *
  * Charset ascii translation tables.
  * Generated automatically from the Unicode and charset
index b1317ad5ca1851f0ba4954d7bb47bba1bd239213..7dfdab98729bfd30666e71f8a34ad4ea375a7543 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_base.c
+ * linux/fs/nls/nls_base.c
  *
  * Native language support--charsets and unicode translations.
  * By Gordon Chaffee 1996, 1997
index 32e78cf9518064641fce0e511de68db08cb0cf5d..570aa69846a0343a85770bfcd5ecce0ba5010976 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1250.c
+ * linux/fs/nls/nls_cp1250.c
  *
  * Charset cp1250 translation tables.
  * Generated automatically from the Unicode and charset
index cb41c8ae4486c0e0b3cd7506257b30531046c9f9..f114afa069dbd2289fcc50f63331de50bb938021 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1251.c
+ * linux/fs/nls/nls_cp1251.c
  *
  * Charset cp1251 translation tables.
  * Generated automatically from the Unicode and charset
index efdeefee53460f145ad9269882b865eeec2b12e5..e57f2cbf5bc070e1a46cc96993f181be1efb9b52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp1255.c
+ * linux/fs/nls/nls_cp1255.c
  *
  * Charset cp1255 translation tables.
  * The Unicode to charset table has only exact mappings.
index 5c4a1cd685dd2a95cb0285293802af39d101bdaf..d41930ce4a44429f097f86602dd506806a0f58a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp437.c
+ * linux/fs/nls/nls_cp437.c
  *
  * Charset cp437 translation tables.
  * Generated automatically from the Unicode and charset
index e8b3ca8462e7443d4be64b728d34c7e5a7970bc2..d21f8790aa19660e3667a0b78a4b7955813cf992 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp737.c
+ * linux/fs/nls/nls_cp737.c
  *
  * Charset cp737 translation tables.
  * Generated automatically from the Unicode and charset
index bdb290ea523ae1510dd5ac61f19a87813466def0..c97714c38a90600e83b0887c79c36143ad6e3e6a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp775.c
+ * linux/fs/nls/nls_cp775.c
  *
  * Charset cp775 translation tables.
  * Generated automatically from the Unicode and charset
index 25deaa4c8648505fafc85cda9399677def2db542..843b7d975ba27365e7df7332371ce050409871be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp850.c
+ * linux/fs/nls/nls_cp850.c
  *
  * Charset cp850 translation tables.
  * Generated automatically from the Unicode and charset
index b822a7b6b970207df3ee82e1941f6b25145923c6..83cfd844d5ca5fa03d179a8325254a906a5d18a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp852.c
+ * linux/fs/nls/nls_cp852.c
  *
  * Charset cp852 translation tables.
  * Generated automatically from the Unicode and charset
index e8641b7a8b27ac39b74a41182cd60811b7a9f41b..9190b7b574ffeff4654ab7fc5d3d18c7d3666800 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp855.c
+ * linux/fs/nls/nls_cp855.c
  *
  * Charset cp855 translation tables.
  * Generated automatically from the Unicode and charset
index 7ba589ef8cc0487e162214068e010a80f2bd43cc..ef3d36db808245f956c8706f7655e4817320303f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp857.c
+ * linux/fs/nls/nls_cp857.c
  *
  * Charset cp857 translation tables.
  * Generated automatically from the Unicode and charset
index 3b9e49ce8c801aa8e4fcedf9114582ac65e49f9b..7e2fb6645893b75982900683950b1a84049da82f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp860.c
+ * linux/fs/nls/nls_cp860.c
  *
  * Charset cp860 translation tables.
  * Generated automatically from the Unicode and charset
index 959ff64ee971962feeb7b0f87a5980a480d014aa..66d8d808ccf1400120a2f8d94329aa8cf2f4cc16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp861.c
+ * linux/fs/nls/nls_cp861.c
  *
  * Charset cp861 translation tables.
  * Generated automatically from the Unicode and charset
index b96928f5a0232ca12bc4f2eb4508c4b2b522acd8..360ba388485fbe31a8825672e23ba242a99b1648 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp862.c
+ * linux/fs/nls/nls_cp862.c
  *
  * Charset cp862 translation tables.
  * Generated automatically from the Unicode and charset
index baa6e0eab1d687c0e4c15a3a2461c0430a2ec8c5..656a93113e37bac396574ccc965b656a3917f4ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp863.c
+ * linux/fs/nls/nls_cp863.c
  *
  * Charset cp863 translation tables.
  * Generated automatically from the Unicode and charset
index f4dabb037dfecada5ea8bffd988eac22b33702da..01ca7309753e9036da17bd6cec51c6cbd4186343 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp864.c
+ * linux/fs/nls/nls_cp864.c
  *
  * Charset cp864 translation tables.
  * Generated automatically from the Unicode and charset
index 4caeafae32c2bb91a5b92a7d98512135d3a6db12..5ba6ee13e109e043d8e265feb5c01e88c663fef9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp865.c
+ * linux/fs/nls/nls_cp865.c
  *
  * Charset cp865 translation tables.
  * Generated automatically from the Unicode and charset
index f2b4a9a293fb1e168853cc98c6d719169041bcb3..c5f82221c9fe4139eec88013d7d7582dc55c1eb3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp866.c
+ * linux/fs/nls/nls_cp866.c
  *
  * Charset cp866 translation tables.
  * Generated automatically from the Unicode and charset
index 12b436f4eca1d52d33e52d8152c324573aaa60a1..8d4015124d11e00ad39b3f8752191c5d7941a36b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp869.c
+ * linux/fs/nls/nls_cp869.c
  *
  * Charset cp869 translation tables.
  * Generated automatically from the Unicode and charset
index b5766a01703a34d8a511b46f9da581c1e82b8260..df042052c2db15bb902d020a53ec65d82effb4c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp874.c
+ * linux/fs/nls/nls_cp874.c
  *
  * Charset cp874 translation tables.
  * Generated automatically from the Unicode and charset
index 2c1a17cdcd245c116fb20a5068ff4ffeb10e7b4a..2a9ccf3bc7efae1d0e6e464ca62467bc890433e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp932.c
+ * linux/fs/nls/nls_cp932.c
  *
  * Charset cp932 translation tables.
  * This translation table was generated automatically, the
index ef4cef464aba98f46785f24be1aa6be1fb8b7181..046fde8170eaf50038d907602106409b3dd104b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp936.c
+ * linux/fs/nls/nls_cp936.c
  *
  * Charset cp936 translation tables.
  * This translation table was generated automatically, the
index 4351ae21d897a3c5ae5b4634f58d66da73693b41..92ae19372f0f08177ad1f619bb11febfe1e1a51c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp949.c
+ * linux/fs/nls/nls_cp949.c
  *
  * Charset cp949 translation tables.
  * This translation table was generated automatically, the
index 8167a28588790558abf6fcd4e69e5ed7a97fd1e7..5665945fb88cc6d648efb58a70b7f42cd312eb4e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_cp950.c
+ * linux/fs/nls/nls_cp950.c
  *
  * Charset cp950 translation tables.
  * This translation table was generated automatically, the
index 06640c3e402102db7e32d5ddf6d742c00c4a935e..73293511578b09355d25d1acad13b968b41e138e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_euc-jp.c
+ * linux/fs/nls/nls_euc-jp.c
  *
  * Added `OSF/JVC Recommended Code Set Conversion Specification
  * between Japanese EUC and Shift-JIS' support: <hirofumi@mail.parknet.co.jp>
index 70a2c19567233e5178f7096d029c9cbf95aa7c05..2483c3c6c1c16b64669e3c83ed7e8b0b520325d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-1.c
+ * linux/fs/nls/nls_iso8859-1.c
  *
  * Charset iso8859-1 translation tables.
  * Generated automatically from the Unicode and charset
index 4547035f21a350184dc3dde9cf73d53b949e4d9a..7b8721d7436855950a0ef042d4e37344d84cefb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-13.c
+ * linux/fs/nls/nls_iso8859-13.c
  *
  * Charset iso8859-13 translation tables.
  * The Unicode to charset table has only exact mappings.
index 13628d0dd3a969b76feb5a779c8735961af8afc4..2e895e638dba5091d2cd935b76998b71df6ea4fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-14.c
+ * linux/fs/nls/nls_iso8859-14.c
  *
  * Charset iso8859-14 translation tables.
  *
index 88b924bf7e186298377e800450c6bacb49352040..5c91592779fe79849141aaf24121e81f8804af23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-15.c
+ * linux/fs/nls/nls_iso8859-15.c
  *
  * Charset iso8859-15 translation tables.
  * The Unicode to charset table has only exact mappings.
index 372528a6c40c910f1e653452c4302506ef5dc2c7..892d38fe95303ad8dcc92dd63aea42803d49e9a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-2.c
+ * linux/fs/nls/nls_iso8859-2.c
  *
  * Charset iso8859-2 translation tables.
  * Generated automatically from the Unicode and charset
index 81b45a234369f08c1a30b1ca92e76f613c3919fe..49317bcdb4be7330684f1bf36088c124d7dd0cc7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-3.c
+ * linux/fs/nls/nls_iso8859-3.c
  *
  * Charset iso8859-3 translation tables.
  * Generated automatically from the Unicode and charset
index 101b87f5a49b71bb80c837e9ce848286bc8f183a..9f3b9368c2cfc7519d27bfec1704414b5fedd9ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-4.c
+ * linux/fs/nls/nls_iso8859-4.c
  *
  * Charset iso8859-4 translation tables.
  * Generated automatically from the Unicode and charset
index 83b0084de5ebd043dbf272c191fe03c560574de9..001a2bb132cece6f61f729bb55fde89e649a7974 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-5.c
+ * linux/fs/nls/nls_iso8859-5.c
  *
  * Charset iso8859-5 translation tables.
  * Generated automatically from the Unicode and charset
index 0c519d65f55b728f0509bc043a24fcda5ff66c2e..8cec03d66088cf63781c3180ae1c55419a015857 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-6.c
+ * linux/fs/nls/nls_iso8859-6.c
  *
  * Charset iso8859-6 translation tables.
  * Generated automatically from the Unicode and charset
index bd0854625acfbb5f1a12e426b65fd8dd0827a3c6..1be707d5ac3149b208d013eadca113632ace9968 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-7.c
+ * linux/fs/nls/nls_iso8859-7.c
  *
  * Charset iso8859-7 translation tables.
  * Generated automatically from the Unicode and charset
index 988eff791c06bb741fb147abee17f2c2c5bee52c..8c0146f73834b694ef2836bd0640d8f9ce6081a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_iso8859-9.c
+ * linux/fs/nls/nls_iso8859-9.c
  *
  * Charset iso8859-9 translation tables.
  * Generated automatically from the Unicode and charset
index 0ad22c249796f4f2693f8d375cdd4ad5ed7652cd..fefbe0807265bbf838321894f38be9bf4791ccb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-r.c
+ * linux/fs/nls/nls_koi8-r.c
  *
  * Charset koi8-r translation tables.
  * Generated automatically from the Unicode and charset
index 5db83efe27c66a76b7594d3befedc601d08d2b41..e7bc1d75c78c4e9a79a373707559ab51f091d456 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-ru.c
+ * linux/fs/nls/nls_koi8-ru.c
  *
  * Charset koi8-ru translation based on charset koi8-u.
  * The Unicode to charset table has only exact mappings.
index 9d30fd61cf46bf69092f254c55dfc15a5cd7ce55..015070211f229d721b73db16ad8edc32895c83c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls_koi8-u.c
+ * linux/fs/nls/nls_koi8-u.c
  *
  * Charset koi8-u translation tables.
  * The Unicode to charset table has only exact mappings.
index 41f24369e47a0945e67fd52a10fa3bcabc357943..c093642fb983b4627e94793b3268cde7c9d4c308 100644 (file)
@@ -38,8 +38,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
        int err;
        int jbegin_failure = 0;
 
-       if (!S_ISREG(inode->i_mode))
-               BUG();
+       BUG_ON(!S_ISREG(inode->i_mode));
 
        /* fast out for when nothing needs to be done */
        if ((atomic_read(&inode->i_count) > 1 ||
@@ -125,8 +124,7 @@ static int reiserfs_sync_file(struct file *p_s_filp,
        int n_err;
        int barrier_done;
 
-       if (!S_ISREG(p_s_inode->i_mode))
-               BUG();
+       BUG_ON(!S_ISREG(p_s_inode->i_mode));
        n_err = sync_mapping_buffers(p_s_inode->i_mapping);
        reiserfs_write_lock(p_s_inode->i_sb);
        barrier_done = reiserfs_commit_for_inode(p_s_inode);
index 7e5a2f5ebeb0fc19e120a5d9f29c00c37b89624f..9c69bcacad2286c1e7a926bf2a5000ae9d84da64 100644 (file)
@@ -1780,7 +1780,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                err = -EDQUOT;
                goto out_end_trans;
        }
-       if (!dir || !dir->i_nlink) {
+       if (!dir->i_nlink) {
                err = -EPERM;
                goto out_bad_inode;
        }
index 7a88adbceef6ece45562579d2c24cdb6b196d33e..b9b423b22a8b1dcf6dab19723a4f8bfa64e0e4a3 100644 (file)
@@ -75,8 +75,7 @@ static int sd_create_vi(struct virtual_node *vn,
 static int sd_check_left(struct virtual_item *vi, int free,
                         int start_skip, int end_skip)
 {
-       if (start_skip || end_skip)
-               BUG();
+       BUG_ON(start_skip || end_skip);
        return -1;
 }
 
@@ -87,8 +86,7 @@ static int sd_check_right(struct virtual_item *vi, int free)
 
 static int sd_part_size(struct virtual_item *vi, int first, int count)
 {
-       if (count)
-               BUG();
+       BUG_ON(count);
        return 0;
 }
 
@@ -476,8 +474,7 @@ static int direntry_create_vi(struct virtual_node *vn,
 
        vi->vi_index = TYPE_DIRENTRY;
 
-       if (!(vi->vi_ih) || !vi->vi_item)
-               BUG();
+       BUG_ON(!(vi->vi_ih) || !vi->vi_item);
 
        dir_u->flags = 0;
        if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)
@@ -575,8 +572,7 @@ static int direntry_check_right(struct virtual_item *vi, int free)
                free -= dir_u->entry_sizes[i];
                entries++;
        }
-       if (entries == dir_u->entry_count)
-               BUG();
+       BUG_ON(entries == dir_u->entry_count);
 
        /* "." and ".." can not be separated from each other */
        if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
index e6b5ccf23f152178eb2981423ae3218f1abab6c0..ad8cbc49883ab7d1e1051f9c72dff211b45a80e8 100644 (file)
@@ -718,8 +718,7 @@ static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
                        spinlock_t * lock, void (fn) (struct buffer_chunk *))
 {
        int ret = 0;
-       if (chunk->nr >= CHUNK_SIZE)
-               BUG();
+       BUG_ON(chunk->nr >= CHUNK_SIZE);
        chunk->bh[chunk->nr++] = bh;
        if (chunk->nr >= CHUNK_SIZE) {
                ret = 1;
@@ -788,8 +787,7 @@ static inline int __add_jh(struct reiserfs_journal *j, struct buffer_head *bh,
                /* buffer must be locked for __add_jh, should be able to have
                 * two adds at the same time
                 */
-               if (bh->b_private)
-                       BUG();
+               BUG_ON(bh->b_private);
                jh->bh = bh;
                bh->b_private = jh;
        }
@@ -2967,8 +2965,7 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
        int retval;
 
        reiserfs_check_lock_depth(p_s_sb, "journal_begin");
-       if (nblocks > journal->j_trans_max)
-               BUG();
+       BUG_ON(nblocks > journal->j_trans_max);
 
        PROC_INFO_INC(p_s_sb, journal.journal_being);
        /* set here for journal_join */
@@ -3084,9 +3081,8 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
        if (reiserfs_transaction_running(s)) {
                th = current->journal_info;
                th->t_refcount++;
-               if (th->t_refcount < 2) {
-                       BUG();
-               }
+               BUG_ON(th->t_refcount < 2);
+               
                return th;
        }
        th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
@@ -3126,9 +3122,7 @@ static int journal_join(struct reiserfs_transaction_handle *th,
         ** pointer
         */
        th->t_handle_save = cur_th;
-       if (cur_th && cur_th->t_refcount > 1) {
-               BUG();
-       }
+       BUG_ON(cur_th && cur_th->t_refcount > 1);
        return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN);
 }
 
@@ -3141,9 +3135,7 @@ int journal_join_abort(struct reiserfs_transaction_handle *th,
         ** pointer
         */
        th->t_handle_save = cur_th;
-       if (cur_th && cur_th->t_refcount > 1) {
-               BUG();
-       }
+       BUG_ON(cur_th && cur_th->t_refcount > 1);
        return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT);
 }
 
@@ -3178,8 +3170,7 @@ int journal_begin(struct reiserfs_transaction_handle *th,
                current->journal_info = th;
        }
        ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG);
-       if (current->journal_info != th)
-               BUG();
+       BUG_ON(current->journal_info != th);
 
        /* I guess this boils down to being the reciprocal of clm-2100 above.
         * If do_journal_begin_r fails, we need to put it back, since journal_end
@@ -3324,8 +3315,7 @@ int journal_end(struct reiserfs_transaction_handle *th,
                /* we aren't allowed to close a nested transaction on a different
                 ** filesystem from the one in the task struct
                 */
-               if (cur_th->t_super != th->t_super)
-                       BUG();
+               BUG_ON(cur_th->t_super != th->t_super);
 
                if (th != cur_th) {
                        memcpy(current->journal_info, th, sizeof(*th));
@@ -3444,9 +3434,7 @@ int journal_end_sync(struct reiserfs_transaction_handle *th,
 
        BUG_ON(!th->t_trans_id);
        /* you can sync while nested, very, very bad */
-       if (th->t_refcount > 1) {
-               BUG();
-       }
+       BUG_ON(th->t_refcount > 1);
        if (journal->j_len == 0) {
                reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb),
                                             1);
@@ -3556,9 +3544,8 @@ static int check_journal_end(struct reiserfs_transaction_handle *th,
         ** will be dealt with by next transaction that actually writes something, but should be taken
         ** care of in this trans
         */
-       if (journal->j_len == 0) {
-               BUG();
-       }
+       BUG_ON(journal->j_len == 0);
+
        /* if wcount > 0, and we are called to with flush or commit_now,
         ** we wait on j_join_wait.  We will wake up when the last writer has
         ** finished the transaction, and started it on its way to the disk.
@@ -3592,9 +3579,8 @@ static int check_journal_end(struct reiserfs_transaction_handle *th,
                                        unlock_journal(p_s_sb);
                                }
                        }
-                       if (journal->j_trans_id == trans_id) {
-                               BUG();
-                       }
+                       BUG_ON(journal->j_trans_id == trans_id);
+                       
                        if (commit_now
                            && journal_list_still_alive(p_s_sb, trans_id)
                            && wait_on_commit) {
@@ -4074,9 +4060,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
        set_commit_trans_len(commit, journal->j_len);
 
        /* special check in case all buffers in the journal were marked for not logging */
-       if (journal->j_len == 0) {
-               BUG();
-       }
+       BUG_ON(journal->j_len == 0);
 
        /* we're about to dirty all the log blocks, mark the description block
         * dirty now too.  Don't mark the commit block dirty until all the
@@ -4173,8 +4157,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
                                      journal, jl, &jl->j_tail_bh_list);
                lock_kernel();
        }
-       if (!list_empty(&jl->j_tail_bh_list))
-               BUG();
+       BUG_ON(!list_empty(&jl->j_tail_bh_list));
        up(&jl->j_commit_lock);
 
        /* honor the flush wishes from the caller, simple commits can
index 16e9cff8f15de9e2884079adb426a3f476445be8..abde1edc2235605c9a4a9680cfdcafbf830f6a12 100644 (file)
@@ -67,8 +67,7 @@ inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de)
 {
        struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-       if (de->de_entry_num >= ih_entry_count(de->de_ih))
-               BUG();
+       BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
 
        de->de_entrylen = entry_length(de->de_bh, de->de_ih, de->de_entry_num);
        de->de_namelen = de->de_entrylen - (de_with_sd(deh) ? SD_SIZE : 0);
@@ -80,8 +79,7 @@ inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de)
 // what entry points to
 static inline void set_de_object_key(struct reiserfs_dir_entry *de)
 {
-       if (de->de_entry_num >= ih_entry_count(de->de_ih))
-               BUG();
+       BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
        de->de_dir_id = deh_dir_id(&(de->de_deh[de->de_entry_num]));
        de->de_objectid = deh_objectid(&(de->de_deh[de->de_entry_num]));
 }
@@ -90,8 +88,7 @@ static inline void store_de_entry_key(struct reiserfs_dir_entry *de)
 {
        struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-       if (de->de_entry_num >= ih_entry_count(de->de_ih))
-               BUG();
+       BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
 
        /* store key of the found entry */
        de->de_entry_key.version = KEY_FORMAT_3_5;
index 8b9b131271363f2f9b3ef5ed9bcd7fa55a35cab2..5240abe1a709df1411785d61a66cc64d28d8abf4 100644 (file)
@@ -1476,9 +1476,7 @@ static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th,
        int n_block_size = p_s_sb->s_blocksize;
        int cut_bytes;
        BUG_ON(!th->t_trans_id);
-
-       if (n_new_file_size != p_s_inode->i_size)
-               BUG();
+       BUG_ON(n_new_file_size != p_s_inode->i_size);
 
        /* the page being sent in could be NULL if there was an i/o error
         ** reading in the last block.  The user will hit problems trying to
index 36fbeccdc722c27a5492076fad587b13f98d5e8c..c75f68361e33dda4276b29583b5d45d8f33afd15 100644 (file)
@@ -53,8 +53,7 @@ cmn_err(register int level, char *fmt, ...)
        va_end(ap);
        spin_unlock_irqrestore(&xfs_err_lock,flags);
 
-       if (level == CE_PANIC)
-               BUG();
+       BUG_ON(level == CE_PANIC);
 }
 
 void
@@ -72,8 +71,7 @@ icmn_err(register int level, char *fmt, va_list ap)
                strcat(message, "\n");
        spin_unlock_irqrestore(&xfs_err_lock,flags);
        printk("%s%s", err_level[level], message);
-       if (level == CE_PANIC)
-               BUG();
+       BUG_ON(level == CE_PANIC);
 }
 
 void
index 21f6ee4858191bc46f5580f553f834a21e1f7caa..de4481dd8ba0ebe6fbc21dc11f9c9bcf9e55ee52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-CLPS711x/entry-macro.S
+ * include/asm-arm/arch-clps711x/entry-macro.S
  *
  * Low-level IRQ helper macros for CLPS711X-based platforms
  *
index cf10ac96fdded85a3a97fd26442c92328942d9b0..ce812d4f4a33687cdbd2deeadfec5508331619fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-footbridge/entry-macro.S
+ * include/asm-arm/arch-ebsa285/entry-macro.S
  *
  * Low-level IRQ helper macros for footbridge-based platforms
  *
index 09eda84592ffc03a0cb2f967d44d3f3d0f669197..8dc1460b23052a09123cba8394ab0899622e72dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-h720x/system.h
+ * linux/include/asm-arm/arch-h720x/system.h
  *
  * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc.
  *
index 73589aad8dd60218f1c83e50743c155af33e453e..8e1db423b1cc2d0509cecd93d1a7fafcd32f60d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-ixp4x//system.h 
+ * include/asm-arm/arch-ixp4xx/system.h
  *
  * Copyright (C) 2002 Intel Corporation.
  *
index b5f3a71b899dbdb836394f84652831151b4390a5..fefb276ed40249a179716df85d1858f35e04e238 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arm/arch-omap/dmtimer.h
+ * linux/include/asm-arm/arch-omap/dmtimer.h
  *
  * OMAP Dual-Mode Timers
  *
index ed0dde4f7219643c961e4f7b259c5817c3c12481..c7a0cc1c4e93969d7c6a2b375ba63ccb5489b318 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-omap/gpio.h
+ * linux/include/asm-arm/arch-omap/mcbsp.h
  *
  * Defines for Multi-Channel Buffered Serial Port
  *
index e46623c61a729aca1df5547c7cfc2b52d070618b..14588059981f99cf8f8f299d5f79292c1b8e9fb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm/arch-omap/pm.h
+ * linux/include/asm-arm/arch-omap/pm.h
  *
  * Header file for OMAP Power Management Routines
  *
index 485a3651b4d7e4e97500e92d7065f518c4145d4b..2613c7c669b171338a854de28c555915b334e045 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-pnx4008/platfrom.h
+ * include/asm-arm/arch-pnx4008/platform.h
  *
  * PNX4008 Base addresses - header file
  *
index 71161797bc8988ef8725920ad122141ef73ec97b..90894214cace08f12b7c1c227e5ea5c65831050e 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/fb.h
+/* linux/include/asm-arm/arch-s3c2410/fb.h
  *
  * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
  *
index c7b90b3ecc9e3f78b2801591649c88772d86f5b4..3196a2849e8ae508061339b45ff4e2426d84698a 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-adc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-adc.h
  *
  * Copyright (c) 2004 Shannon Holland <holland@loser.net>
  *
index b2f4690c079171758c37558afc79e86238de4c52..e39656b7a08625188ac3b190b5fdce002e7b721b 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-clock.h
+/* linux/include/asm-arm/arch-s3c2410/regs-clock.h
  *
  * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
  *                   http://armlinux.simtec.co.uk/
index a0a1248751646053c9f969cf1f0d181b1911de68..c0748511edbc848c7e16faa97b8bfa491025c6f7 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-dsc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-dsc.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 93c49432db9564de3776909ec3b9a51bd8ae1c6a..b2893e32a2361741495899263cdababce5324034 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-gpio.h
+/* linux/include/asm-arm/arch-s3c2410/regs-gpio.h
  *
  * Copyright (c) 2003,2004 Simtec Electronics <linux@simtec.co.uk>
  *                        http://www.simtec.co.uk/products/SWLINUX/
index 91cefa260497464648b5538af1c3ad16e2315fbb..02131a5a1d3af14f9a4dd7cf3ff8db5265a0bc97 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/hardware/s3c2410/regs-gpioj.h
+/* linux/include/asm-arm/arch-s3c2410/regs-gpioj.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 72cd2509822e1997e9410a4c8ea8cca1d75600ef..eaf77916a602e1b1710b5288f1f30903a82dff64 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-iis.h
+/* linux/include/asm-arm/arch-s3c2410/regs-iis.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 29fb8ef670f07d58db7007dd9e4411638e4f663b..498184cb8adcf5381af3bb757414544e17bf77b5 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-irq.h
+/* linux/include/asm-arm/arch-s3c2410/regs-irq.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 6d7881c8cfc8ee35077a018f56b17a1a7f2d98ba..b7faeb04c0ffb1afcabc0225aaa68c8a6784bf7d 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-lcd.h
+/* linux/include/asm-arm/arch-s3c2410/regs-lcd.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index cd88fd634d12b5d8b4a5bc57a675e8c0c2704d06..93b03c49710a561783ef47d1742ba1678d78d4f7 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-rtc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-rtc.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 06e716e5b46d16e3fae2d7a80307c384f65a11ad..bb9d30b72952c88e684c17ca42e1147367084652 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-sdi.h
+/* linux/include/asm-arm/arch-s3c2410/regs-sdi.h
  *
  * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 731918e778310387b586246fa0aa081443ef397f..6f8fe432fe3a982e38ea005a2cae94204d0db446 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-timer.h
+/* linux/include/asm-arm/arch-s3c2410/regs-timer.h
  *
  * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
  *                   http://www.simtec.co.uk/products/SWLINUX/
index 3aa31a27da1addecc93ebd4c32eb0f3ebe064512..487861d5b49a98745f27a9da429c91dad5f4b0fd 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/regs-udc.h
+/* linux/include/asm-arm/arch-s3c2410/regs-udc.h
  *
  * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
  *
index 258c00bca2706f875ecdf089846f0ea84821edd1..c1e4db7c971039e95b51c4b1db733b32b8cea458 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/arch-s3c2410/spi.h
+/* linux/include/asm-arm/arch-s3c2410/spi-gpio.h
  *
  * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
index 8051fd73a80bc9268b945c1b6da1868fa19f6679..09ec9e2bd1820ba488e87f877b1939f567088980 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-sa1100/assabet.h
+ * linux/include/asm-arm/arch-sa1100/neponset.h
  *
  * Created 2000/06/05 by Nicolas Pitre <nico@cam.org>
  *
index 2601a77a6ddaede178a1222e6d18252b3aac22f1..17e64d232e7dfcb7831ffe488de2bf709eb7572f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-brutus/uncompress.h
+ * linux/include/asm-arm/arch-sa1100/uncompress.h
  *
  * (C) 1999 Nicolas Pitre <nico@cam.org>
  *
index 10db5d188231bc1de1bf15164ca2c88251af859f..fac37c636b38fa4dadc756d314203e0812d3cb5a 100644 (file)
@@ -1,4 +1,4 @@
 /*
- * linux/include/asm-arm/arch-rpc/vmalloc.h
+ * linux/include/asm-arm/arch-shark/vmalloc.h
  */
 #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
index 4594fea91ec1cfdf521670a3fcc982bd04171ee3..07c97fb233fcd50d4963fe9e3b4f8201251dde16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/hardware/debug-8250.h
+ * linux/include/asm-arm/hardware/debug-8250.S
  *
  *  Copyright (C) 1994-1999 Russell King
  *
index db0d0f7de5e9c400418abd37d0c0ccc27f0a301c..23c541a9e89abc896098de362fee893d0eeb4297 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/arch-integrator/debug-macro.S
+/* linux/include/asm-arm/hardware/debug-pl01x.S
  *
  * Debugging macro include header
  *
index 30c7b92c24164e56f53e9a91264ceeac5126a745..fbed08f298d0701d19ef9fc14b6eda72bdb40792 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * arch/arm/commond/entry-macro-iomd.S
+ * include/asm-arm/hardware/entry-macro-iomd.S
  *
  * Low-level IRQ helper macros for IOC/IOMD based platforms
  *
index 319aea064c367ee29c664c499b4bd6d3b6e19a40..6aa0a5b75b69dc9bc5f72266f8df5763f9c561eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/hardware/SA-1111.h
+ * linux/include/asm-arm/hardware/sa1111.h
  *
  * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
  *
index 83f9aec55e4f943190cdf2ccb1d446b966f65247..bb507a9a4a554d3c94ca4a97af40bd9e353a8764 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/asm/assembler.h
+ * linux/include/asm-arm26/assembler.h
  *
  * This file contains arm architecture specific defines
  * for the different processors.
index a402d3b9d0f76489ff5ec0f6448a21d47309965b..3f5d340110eb98bc5668d1c39ab699ab6a309a34 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * linux/include/asm-arm/namei.h
+ * linux/include/asm-arm26/namei.h
  *
  * Routines to handle famous /usr/gnemul
  * Derived from the Sparc version of this file
index ccf15e7041092d01f520c22772773678b41b4e73..1fda54375ed8293aab492d707287da37923f6bf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/semaphore.h
+ * linux/include/asm-arm26/semaphore.h
  */
 #ifndef __ASM_ARM_SEMAPHORE_H
 #define __ASM_ARM_SEMAPHORE_H
index 84ddd6445f23ae6cd5d12aec91552be4a4ef39d0..4ea57171d9516be6964702d0be919950c1145442 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm/namei.h
+ * include/asm-frv/namei.h
  *
  * Included from linux/fs/namei.c
  */
index 29c6ac34e236f48ab1704bfda30350b453a3c6af..0134151656af2f8d5b0def7315f8108c6644cadf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-dec.h
+ * include/asm-generic/mutex-dec.h
  *
  * Generic implementation of the mutex fastpath, based on atomic
  * decrement/increment.
index 254a126ede5c694fc4b024c5b43c192c13b928d8..e1bbbc72b6a257adc7b5c1ad0dc95b9d615e0872 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-null.h
+ * include/asm-generic/mutex-null.h
  *
  * Generic implementation of the mutex fastpath, based on NOP :-)
  *
index 32a2100c1aebf112639ce9b05e59ca5c182603e0..6a7e8c141b536d66a6bc0149ad33c339ad040925 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm-generic/mutex-xchg.h
+ * include/asm-generic/mutex-xchg.h
  *
  * Generic implementation of the mutex fastpath, based on xchg().
  *
index 4087037a42259be8c990266ca18744d58457a9b5..d3238f1f70a684c109df2f4b976e2bc89eff22f2 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * inclue/asm-generic/rtc.h
+ * include/asm-generic/rtc.h
  *
  * Author: Tom Rini <trini@mvista.com>
  *
index 867d9008fafa9434417f1cecd46f2489e140b872..f490e43a90b90a09e1cfe78a9f1215b66d3df74e 100644 (file)
@@ -1,4 +1,4 @@
-/* asm-generic/tlb.h
+/* include/asm-generic/tlb.h
  *
  *     Generic TLB shootdown code
  *
index 87e5a351d8812b369bf1fc88187214d947d87fa9..88f02a0735615d7be2796249ad9bbb73036a4e20 100644 (file)
@@ -17,8 +17,6 @@
 #include <asm/irq.h>
 #include <asm/sections.h>
 
-struct hw_interrupt_type;
-
 #define NMI_VECTOR             0x02
 
 /*
@@ -30,7 +28,6 @@ struct hw_interrupt_type;
 
 extern u8 irq_vector[NR_IRQ_VECTORS];
 #define IO_APIC_VECTOR(irq)    (irq_vector[irq])
-#define AUTO_ASSIGN            -1
 
 extern void (*interrupt[NR_IRQS])(void);
 
diff --git a/include/asm-i386/hypertransport.h b/include/asm-i386/hypertransport.h
new file mode 100644 (file)
index 0000000..c16c6ff
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef ASM_HYPERTRANSPORT_H
+#define ASM_HYPERTRANSPORT_H
+
+/*
+ * Constants for x86 Hypertransport Interrupts.
+ */
+
+#define HT_IRQ_LOW_BASE                        0xf8000000
+
+#define HT_IRQ_LOW_VECTOR_SHIFT                16
+#define  HT_IRQ_LOW_VECTOR_MASK                0x00ff0000
+#define  HT_IRQ_LOW_VECTOR(v)          (((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
+
+#define HT_IRQ_LOW_DEST_ID_SHIFT       8
+#define  HT_IRQ_LOW_DEST_ID_MASK       0x0000ff00
+#define  HT_IRQ_LOW_DEST_ID(v)         (((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
+
+#define HT_IRQ_LOW_DM_PHYSICAL         0x0000000
+#define HT_IRQ_LOW_DM_LOGICAL          0x0000040
+
+#define HT_IRQ_LOW_RQEOI_EDGE          0x0000000
+#define HT_IRQ_LOW_RQEOI_LEVEL         0x0000020
+
+
+#define HT_IRQ_LOW_MT_FIXED            0x0000000
+#define HT_IRQ_LOW_MT_ARBITRATED       0x0000004
+#define HT_IRQ_LOW_MT_SMI              0x0000008
+#define HT_IRQ_LOW_MT_NMI              0x000000c
+#define HT_IRQ_LOW_MT_INIT             0x0000010
+#define HT_IRQ_LOW_MT_STARTUP          0x0000014
+#define HT_IRQ_LOW_MT_EXTINT           0x0000018
+#define HT_IRQ_LOW_MT_LINT1            0x000008c
+#define HT_IRQ_LOW_MT_LINT0            0x0000098
+
+#define HT_IRQ_LOW_IRQ_MASKED          0x0000001
+
+
+#define HT_IRQ_HIGH_DEST_ID_SHIFT      0
+#define  HT_IRQ_HIGH_DEST_ID_MASK      0x00ffffff
+#define  HT_IRQ_HIGH_DEST_ID(v)                ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
+
+#endif /* ASM_HYPERTRANSPORT_H */
index 5d309275a1dc13aef51ab44383c6edd98081b99a..276ea7e8144ae3cfc8e58b7819ae59c126f90578 100644 (file)
 
 #ifdef CONFIG_X86_IO_APIC
 
-#ifdef CONFIG_PCI_MSI
-static inline int use_pci_vector(void) {return 1;}
-static inline void disable_edge_ioapic_vector(unsigned int vector) { }
-static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
-static inline void end_edge_ioapic_vector (unsigned int vector) { }
-#define startup_level_ioapic   startup_level_ioapic_vector
-#define shutdown_level_ioapic  mask_IO_APIC_vector
-#define enable_level_ioapic    unmask_IO_APIC_vector
-#define disable_level_ioapic   mask_IO_APIC_vector
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
-#define end_level_ioapic       end_level_ioapic_vector
-#define set_ioapic_affinity    set_ioapic_affinity_vector
-
-#define startup_edge_ioapic    startup_edge_ioapic_vector
-#define shutdown_edge_ioapic   disable_edge_ioapic_vector
-#define enable_edge_ioapic     unmask_IO_APIC_vector
-#define disable_edge_ioapic    disable_edge_ioapic_vector
-#define ack_edge_ioapic        ack_edge_ioapic_vector
-#define end_edge_ioapic        end_edge_ioapic_vector
-#else
-static inline int use_pci_vector(void) {return 0;}
-static inline void disable_edge_ioapic_irq(unsigned int irq) { }
-static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
-static inline void end_edge_ioapic_irq (unsigned int irq) { }
-#define startup_level_ioapic   startup_level_ioapic_irq
-#define shutdown_level_ioapic  mask_IO_APIC_irq
-#define enable_level_ioapic    unmask_IO_APIC_irq
-#define disable_level_ioapic   mask_IO_APIC_irq
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
-#define end_level_ioapic       end_level_ioapic_irq
-#define set_ioapic_affinity    set_ioapic_affinity_irq
-
-#define startup_edge_ioapic    startup_edge_ioapic_irq
-#define shutdown_edge_ioapic   disable_edge_ioapic_irq
-#define enable_edge_ioapic     unmask_IO_APIC_irq
-#define disable_edge_ioapic    disable_edge_ioapic_irq
-#define ack_edge_ioapic        ack_edge_ioapic_irq
-#define end_edge_ioapic        end_edge_ioapic_irq
-#endif
-
 #define IO_APIC_BASE(idx) \
                ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
                + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
@@ -219,6 +179,4 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 static inline void disable_ioapic_setup(void) { }
 #endif
 
-extern int assign_irq_vector(int irq);
-
 #endif
index b330026e6f7ff2d95cdb8fb3ad8b0642462379aa..7f161e760be6670879fa5eaa78b0fbc8e97c5a7b 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef _ASM_IRQ_VECTORS_LIMITS_H
 #define _ASM_IRQ_VECTORS_LIMITS_H
 
-#ifdef CONFIG_PCI_MSI
-#define NR_IRQS FIRST_SYSTEM_VECTOR
-#define NR_IRQ_VECTORS NR_IRQS
-#else
 #ifdef CONFIG_X86_IO_APIC
 #define NR_IRQS 224
 # if (224 >= 32 * NR_CPUS)
@@ -16,6 +12,5 @@
 #define NR_IRQS 16
 #define NR_IRQ_VECTORS NR_IRQS
 #endif
-#endif
 
 #endif /* _ASM_IRQ_VECTORS_LIMITS_H */
index 254a0fe01c6a3f46b5983afc9336b11a61a3d81d..ef0671e5d5c549f244daa69be31acb46583b36ca 100644 (file)
@@ -88,7 +88,7 @@ static inline void clustered_apic_check(void)
 
 static inline int apicid_to_node(int logical_apicid)
 {
-       return apicid_2_node[logical_apicid];
+       return apicid_2_node[hard_smp_processor_id()];
 }
 
 /* Mapping from cpu number to logical apicid */
diff --git a/include/asm-i386/msi.h b/include/asm-i386/msi.h
deleted file mode 100644 (file)
index b11c4b7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#include <asm/desc.h>
-#include <mach_apic.h>
-
-#define LAST_DEVICE_VECTOR     (FIRST_SYSTEM_VECTOR - 1)
-#define MSI_TARGET_CPU_SHIFT   12
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-       msi_register(&msi_apic_ops);
-       return 0;
-}
-
-#endif /* ASM_MSI_H */
diff --git a/include/asm-i386/msidef.h b/include/asm-i386/msidef.h
new file mode 100644 (file)
index 0000000..5b8acdd
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef ASM_MSIDEF_H
+#define ASM_MSIDEF_H
+
+/*
+ * Constants for Intel APIC based MSI messages.
+ */
+
+/*
+ * Shifts for MSI data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT          0
+#define  MSI_DATA_VECTOR_MASK          0x000000ff
+#define         MSI_DATA_VECTOR(v)             (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT   8
+#define  MSI_DATA_DELIVERY_FIXED       (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define  MSI_DATA_DELIVERY_LOWPRI      (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT           14
+#define         MSI_DATA_LEVEL_DEASSERT        (0 << MSI_DATA_LEVEL_SHIFT)
+#define         MSI_DATA_LEVEL_ASSERT          (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT         15
+#define  MSI_DATA_TRIGGER_EDGE         (0 << MSI_DATA_TRIGGER_SHIFT)
+#define  MSI_DATA_TRIGGER_LEVEL                (1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for msi address
+ */
+
+#define MSI_ADDR_BASE_HI               0
+#define MSI_ADDR_BASE_LO               0xfee00000
+
+#define MSI_ADDR_DEST_MODE_SHIFT       2
+#define  MSI_ADDR_DEST_MODE_PHYSICAL   (0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define         MSI_ADDR_DEST_MODE_LOGICAL     (1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT     3
+#define  MSI_ADDR_REDIRECTION_CPU      (0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
+#define  MSI_ADDR_REDIRECTION_LOWPRI   (1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */
+
+#define MSI_ADDR_DEST_ID_SHIFT         12
+#define         MSI_ADDR_DEST_ID_MASK          0x00ffff0
+#define  MSI_ADDR_DEST_ID(dest)                (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)
+
+#endif /* ASM_MSIDEF_H */
index 15b545a897a4b6a05843f12f4691c37acad46885..90cba967df356f01e1ea0934819ce4cfdc31c270 100644 (file)
@@ -20,6 +20,7 @@ struct page;
 struct mm_struct;
 struct pci_bus;
 struct task_struct;
+struct pci_dev;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
@@ -75,7 +76,9 @@ typedef unsigned char ia64_mv_readb_relaxed_t (const volatile void __iomem *);
 typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
 typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
 typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
-typedef int ia64_mv_msi_init_t (void);
+
+typedef int ia64_mv_setup_msi_irq_t (unsigned int irq, struct pci_dev *pdev);
+typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq);
 
 static inline void
 machvec_noop (void)
@@ -154,7 +157,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
 #  define platform_readl_relaxed        ia64_mv.readl_relaxed
 #  define platform_readq_relaxed        ia64_mv.readq_relaxed
 #  define platform_migrate             ia64_mv.migrate
-#  define platform_msi_init            ia64_mv.msi_init
+#  define platform_setup_msi_irq       ia64_mv.setup_msi_irq
+#  define platform_teardown_msi_irq    ia64_mv.teardown_msi_irq
 # endif
 
 /* __attribute__((__aligned__(16))) is required to make size of the
@@ -204,7 +208,8 @@ struct ia64_machine_vector {
        ia64_mv_readl_relaxed_t *readl_relaxed;
        ia64_mv_readq_relaxed_t *readq_relaxed;
        ia64_mv_migrate_t *migrate;
-       ia64_mv_msi_init_t *msi_init;
+       ia64_mv_setup_msi_irq_t *setup_msi_irq;
+       ia64_mv_teardown_msi_irq_t *teardown_msi_irq;
 } __attribute__((__aligned__(16))); /* align attrib? see above comment */
 
 #define MACHVEC_INIT(name)                     \
@@ -250,7 +255,8 @@ struct ia64_machine_vector {
        platform_readl_relaxed,                 \
        platform_readq_relaxed,                 \
        platform_migrate,                       \
-       platform_msi_init,                      \
+       platform_setup_msi_irq,                 \
+       platform_teardown_msi_irq,              \
 }
 
 extern struct ia64_machine_vector ia64_mv;
@@ -404,8 +410,11 @@ extern int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size
 #ifndef platform_migrate
 # define platform_migrate machvec_noop_task
 #endif
-#ifndef platform_msi_init
-# define platform_msi_init     ((ia64_mv_msi_init_t*)NULL)
+#ifndef platform_setup_msi_irq
+# define platform_setup_msi_irq                ((ia64_mv_setup_msi_irq_t*)NULL)
+#endif
+#ifndef platform_teardown_msi_irq
+# define platform_teardown_msi_irq     ((ia64_mv_teardown_msi_irq_t*)NULL)
 #endif
 
 #endif /* _ASM_IA64_MACHVEC_H */
index cf724dc79d8c70d25b5db1f771f130f083c48a79..c54b165b1c17a5d045d56795c9c6bc415d2c75d4 100644 (file)
@@ -67,7 +67,8 @@ extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
 extern ia64_mv_dma_mapping_error       sn_dma_mapping_error;
 extern ia64_mv_dma_supported           sn_dma_supported;
 extern ia64_mv_migrate_t               sn_migrate;
-extern ia64_mv_msi_init_t              sn_msi_init;
+extern ia64_mv_setup_msi_irq_t         sn_setup_msi_irq;
+extern ia64_mv_teardown_msi_irq_t      sn_teardown_msi_irq;
 
 
 /*
@@ -120,9 +121,11 @@ extern ia64_mv_msi_init_t          sn_msi_init;
 #define platform_dma_supported         sn_dma_supported
 #define platform_migrate               sn_migrate
 #ifdef CONFIG_PCI_MSI
-#define platform_msi_init              sn_msi_init
+#define platform_setup_msi_irq         sn_setup_msi_irq
+#define platform_teardown_msi_irq      sn_teardown_msi_irq
 #else
-#define platform_msi_init              ((ia64_mv_msi_init_t*)NULL)
+#define platform_setup_msi_irq         ((ia64_mv_setup_msi_irq_t*)NULL)
+#define platform_teardown_msi_irq      ((ia64_mv_teardown_msi_irq_t*)NULL)
 #endif
 
 #include <asm/sn/io.h>
diff --git a/include/asm-ia64/msi.h b/include/asm-ia64/msi.h
deleted file mode 100644 (file)
index bb92b0d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#define NR_VECTORS             NR_IRQS
-#define FIRST_DEVICE_VECTOR    IA64_FIRST_DEVICE_VECTOR
-#define LAST_DEVICE_VECTOR     IA64_LAST_DEVICE_VECTOR
-static inline void set_intr_gate (int nr, void *func) {}
-#define IO_APIC_VECTOR(irq)    (irq)
-#define ack_APIC_irq           ia64_eoi
-#define MSI_TARGET_CPU_SHIFT   4
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-       if (platform_msi_init)
-               return platform_msi_init();
-
-       /* default ops for most ia64 platforms */
-       msi_register(&msi_apic_ops);
-       return 0;
-}
-
-#endif /* ASM_MSI_H */
index 6ba4ddf7dcf788a6d362d342f947aa856ab734c1..cbdbc5891445e25e88658f38bb5a3348eaf57a13 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32104ut/m32104ut_pld.h
+ * include/asm-m32r/m32104ut/m32104ut_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on M32104UT board.
  * Based on m32700ut_pld.h
index c050b19e81010d452494139154a17dcc4677dbdd..f1e47ae1f891da668f3a5c1775ffc2faf9af6c84 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut_lan.h
+ * include/asm-m32r/m32700ut/m32700ut_lan.h
  *
  * M32700UT-LAN board
  *
index 4da4e822e2f38dac6d211da8f4bec1c1ff06e027..e41c4aa48b4cba16d10f8a2bab9a9feab574d3c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut_lcd.h
+ * include/asm-m32r/m32700ut/m32700ut_lcd.h
  *
  * M32700UT-LCD board
  *
index f35f9159acffdb44f32019a164619f3bb3ee2f40..a48c22c978ca14b9305cd3403b510c1d8392a727 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/m32700ut/m32700ut_pld.h
+ * include/asm-m32r/m32700ut/m32700ut_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on M32700UT board.
  *
index 01dcdd19dbe6b680a1cf350d13bc37c537dfc6c9..56a2b12f2bfcfea5eeab087e6d67062e5cb6af80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/mappi2/mappi2_pld.h
+ * include/asm-m32r/mappi2/mappi2_pld.h
  *
  * Definitions for Extended IO Logic on MAPPI2 board.
  *  based on m32700ut_pld.h by
index 031369a7afc85ed732613f483906b826707afecb..92f10defaef8c7d5b1b93204eee3453240f4ce45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/mappi3/mappi3_pld.h
+ * include/asm-m32r/mappi3/mappi3_pld.h
  *
  * Definitions for Extended IO Logic on MAPPI3 board.
  *  based on m32700ut_pld.h
index 61948296f44568921a1fc70b5491785a70f14129..f53e10187c03f377bf3504b7fb44b820453c5a3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput_lan.h
+ * include/asm-m32r/opsput/opsput_lan.h
  *
  * OPSPUT-LAN board
  *
index 44cfd7fe2d88c3cad9675f25c5d183653e77a72a..99f296e1b61b6ee4bc4da2bbaaba0a3eefcdb63e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput_lcd.h
+ * include/asm-m32r/opsput/opsput_lcd.h
  *
  * OPSPUT-LCD board
  *
index 46296fe1ec1a63027c68f22d6d6568cc0d19e15d..a8d6452076f1576dd36c544082c4dcdc56b8056b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm/opsput/opsput_pld.h
+ * include/asm-m32r/opsput/opsput_pld.h
  *
  * Definitions for Programable Logic Device(PLD) on OPSPUT board.
  *
index 71406fc4e599c3d5ed5f625a94850213626cce26..5d3e038598441c58b459c37e30aa1e6b0a09ccc5 100644 (file)
@@ -1,4 +1,4 @@
-/* asm-m68k/rtc.h
+/* include/asm-m68k/rtc.h
  *
  * Copyright Richard Zidlicky
  * implementation details for genrtc/q40rtc driver
index 9d3a1bf412312b1f09847c515b485b179f6ccafe..91cba18acdd32a5f14c220aee136649e88262947 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-m68k/processor.h
+ * include/asm-m68knommu/processor.h
  *
  * Copyright (C) 1995 Hamish Macdonald
  */
index cf89b205f103987ba5610e1bf09ac5d1e8045e48..5f8498fef00566279a19d06ab8ffef0a5613a908 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-mips/tx4938/tx4938_bitmask.h
+ * linux/include/asm-mips/tx4938/tx4938_mips.h
  * Generic bitmask definitions
  *
  * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
index f3d3d6b110baa7515fe45b6fa6b42cb2fad13bc2..f4ebff11dcbd196dffa71edd820328079edd5331 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * inclue/asm-parisc/rtc.h
+ * include/asm-parisc/rtc.h
  *
  * Copyright 2002 Randolph CHung <tausq@debian.org>
  *
index 53079ec3a515be93eb2e7b61a48df6aeddcbe82a..1ce09a35906efd695a1d3cbbb07058eed915a6d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/ipic.h
+ * include/asm-powerpc/ipic.h
  *
  * IPIC external definitions and structure.
  *
index f8f7f16b9b5359293e9c6c7a8152070cd998ffae..5b0704a3e6ea6c6734ef09f7638aa78a0d2011b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/gt64260_defs.h
+ * include/asm-ppc/mv64x60_defs.h
  *
  * Register definitions for the Marvell/Galileo GT64260, MV64360, etc.
  * host bridges.
index 65b93225a7786016845e2a4db544571c743445af..39a10d86224431e20dc9a9e584caa924b05b76cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-ppc/rheap.c
+ * include/asm-ppc/rheap.h
  *
  * Header file for the implementation of a remote heap.
  *
index 05fbf912ab4dafcf785264a2becb03f373f65c5d..6025b46d0a2aae50000310218d4466d732ff6c08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * inclue/asm-ppc/rtc.h
+ * include/asm-ppc/rtc.h
  *
  * Author: Tom Rini <trini@mvista.com>
  *
index a2f37a9353d393c3ec6fac66b3d1cd94b02a4fb7..7189c79bc673e498f4403d7fa36308a66dd2f0b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm/qdio.h
+ * linux/include/asm-s390/qdio.h
  *
  * Linux for S/390 QDIO base support, Hipersocket base support
  * version 2
index 939735ee8dc525e3841f98e93ae6d52af04cd4e2..1470ac8d4a396f90e0808ecfb979e9e6dc914028 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_bigsur.h
+ * include/asm-sh/bigsur/io.h
  *
  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  * Derived from io_hd64465.h, which bore the message:
index 7233af42f75584d5d2c421396061d6541f35bcbe..a08fa82fe45a84c1affe2c00a5e1a0d090247425 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/serial-bigsur.h
+ * include/asm-sh/bigsur/serial.h
  *
  * Configuration details for Big Sur 16550 based serial ports 
  * i.e. HD64465, PCMCIA, etc.
index c8858537803c3d3250a0561f0652d41c74984435..7874e3dac736b1aaa07218752f8e180090725364 100644 (file)
@@ -1,4 +1,4 @@
-/* include/asm-sh/dc_sysasic.h
+/* include/asm-sh/dreamcast/sysasic.h
  *
  * Definitions for the Dreamcast System ASIC and related peripherals.
  *
index 1100bcf4968edab864601e937c4bd9bed5205cda..139f1472e5bbfe00e3c9a4d71820ffc1145e0841 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_hd64465.h
+ * include/asm-sh/hd64465/io.h
  *
  * By Greg Banks <gbanks@pocketpenguins.com>
  * (c) 2000 PocketPenguins Inc.
index eba8a0b5fd7b8f5215620eb33270975032a03bcd..6298370bec2ddf781429280b4625fc91611b55c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/io_mpc1211.h
+ * include/asm-sh/mpc1211/io.h
  *
  * Copyright 2001 Saito.K & Jeanne
  *
index 29c9be15112ba1fbca610958cd7c9a0cc71b33c9..e8d7b3f2da5775317f3ecf58b2e350e0e8ab39fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-sh/serial.h
+ * include/asm-sh64/serial.h
  *
  * Configuration details for 8250, 16450, 16550, etc. serial ports
  */
index ed60ebec59305037d73a97e69b001df725c349ca..ea0a7e590bb3fb1e8ecd9bc2c7be01ee96efda34 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/asm-sparc/reg.h
+ * linux/include/asm-sparc/reg.h
  * Layout of the registers as expected by gdb on the Sparc
  * we should replace the user.h definitions with those in
  * this file, we don't even use the other 
index ed8a9d25272db1e8fe770051f0830efa3a2deb1c..052df758ae61e2df16550e7287d223a82401df8d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-x8664/cache.h
+ * include/asm-x86_64/cache.h
  */
 #ifndef __ARCH_X8664_CACHE_H
 #define __ARCH_X8664_CACHE_H
index 64a65ce2f41fe690033bff1f8ce0d9314b5a9a82..95d5e090ed89eb48d80a6c8b679db973c059d701 100644 (file)
@@ -6,6 +6,9 @@
 #include <asm/pda.h>
 #include <asm/apic.h>
 
+/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
+#define MAX_HARDIRQS_PER_CPU NR_VECTORS
+
 #define __ARCH_IRQ_STAT 1
 
 #define local_softirq_pending() read_pda(__softirq_pending)
index 48a4a5364e85ddfc651c6716e0cf54deeac21df2..53d0d9fd10d62c5986d65644a5251121f35b2c27 100644 (file)
@@ -19,8 +19,7 @@
 #include <asm/irq.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
-
-struct hw_interrupt_type;
+#include <linux/percpu.h>
 #endif
 
 #define NMI_VECTOR             0x02
@@ -75,9 +74,10 @@ struct hw_interrupt_type;
 
 
 #ifndef __ASSEMBLY__
-extern u8 irq_vector[NR_IRQ_VECTORS];
+extern unsigned int irq_vector[NR_IRQ_VECTORS];
+typedef int vector_irq_t[NR_VECTORS];
+DECLARE_PER_CPU(vector_irq_t, vector_irq);
 #define IO_APIC_VECTOR(irq)    (irq_vector[irq])
-#define AUTO_ASSIGN            -1
 
 /*
  * Various low-level irq details needed by irq.c, process.c,
diff --git a/include/asm-x86_64/hypertransport.h b/include/asm-x86_64/hypertransport.h
new file mode 100644 (file)
index 0000000..c16c6ff
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef ASM_HYPERTRANSPORT_H
+#define ASM_HYPERTRANSPORT_H
+
+/*
+ * Constants for x86 Hypertransport Interrupts.
+ */
+
+#define HT_IRQ_LOW_BASE                        0xf8000000
+
+#define HT_IRQ_LOW_VECTOR_SHIFT                16
+#define  HT_IRQ_LOW_VECTOR_MASK                0x00ff0000
+#define  HT_IRQ_LOW_VECTOR(v)          (((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
+
+#define HT_IRQ_LOW_DEST_ID_SHIFT       8
+#define  HT_IRQ_LOW_DEST_ID_MASK       0x0000ff00
+#define  HT_IRQ_LOW_DEST_ID(v)         (((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
+
+#define HT_IRQ_LOW_DM_PHYSICAL         0x0000000
+#define HT_IRQ_LOW_DM_LOGICAL          0x0000040
+
+#define HT_IRQ_LOW_RQEOI_EDGE          0x0000000
+#define HT_IRQ_LOW_RQEOI_LEVEL         0x0000020
+
+
+#define HT_IRQ_LOW_MT_FIXED            0x0000000
+#define HT_IRQ_LOW_MT_ARBITRATED       0x0000004
+#define HT_IRQ_LOW_MT_SMI              0x0000008
+#define HT_IRQ_LOW_MT_NMI              0x000000c
+#define HT_IRQ_LOW_MT_INIT             0x0000010
+#define HT_IRQ_LOW_MT_STARTUP          0x0000014
+#define HT_IRQ_LOW_MT_EXTINT           0x0000018
+#define HT_IRQ_LOW_MT_LINT1            0x000008c
+#define HT_IRQ_LOW_MT_LINT0            0x0000098
+
+#define HT_IRQ_LOW_IRQ_MASKED          0x0000001
+
+
+#define HT_IRQ_HIGH_DEST_ID_SHIFT      0
+#define  HT_IRQ_HIGH_DEST_ID_MASK      0x00ffffff
+#define  HT_IRQ_HIGH_DEST_ID(v)                ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
+
+#endif /* ASM_HYPERTRANSPORT_H */
index 5d1b5c68e36efaf005a3e06408a220249c1f0527..171ec2dc8c04f57e6842cab9ddfd92a4b51751f0 100644 (file)
  * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
  */
 
-#ifdef CONFIG_PCI_MSI
-static inline int use_pci_vector(void) {return 1;}
-static inline void disable_edge_ioapic_vector(unsigned int vector) { }
-static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
-static inline void end_edge_ioapic_vector (unsigned int vector) { }
-#define startup_level_ioapic   startup_level_ioapic_vector
-#define shutdown_level_ioapic  mask_IO_APIC_vector
-#define enable_level_ioapic    unmask_IO_APIC_vector
-#define disable_level_ioapic   mask_IO_APIC_vector
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
-#define end_level_ioapic       end_level_ioapic_vector
-#define set_ioapic_affinity    set_ioapic_affinity_vector
-
-#define startup_edge_ioapic    startup_edge_ioapic_vector
-#define shutdown_edge_ioapic   disable_edge_ioapic_vector
-#define enable_edge_ioapic     unmask_IO_APIC_vector
-#define disable_edge_ioapic    disable_edge_ioapic_vector
-#define ack_edge_ioapic        ack_edge_ioapic_vector
-#define end_edge_ioapic        end_edge_ioapic_vector
-#else
-static inline int use_pci_vector(void) {return 0;}
-static inline void disable_edge_ioapic_irq(unsigned int irq) { }
-static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
-static inline void end_edge_ioapic_irq (unsigned int irq) { }
-#define startup_level_ioapic   startup_level_ioapic_irq
-#define shutdown_level_ioapic  mask_IO_APIC_irq
-#define enable_level_ioapic    unmask_IO_APIC_irq
-#define disable_level_ioapic   mask_IO_APIC_irq
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
-#define end_level_ioapic       end_level_ioapic_irq
-#define set_ioapic_affinity    set_ioapic_affinity_irq
-
-#define startup_edge_ioapic    startup_edge_ioapic_irq
-#define shutdown_edge_ioapic   disable_edge_ioapic_irq
-#define enable_edge_ioapic     unmask_IO_APIC_irq
-#define disable_edge_ioapic    disable_edge_ioapic_irq
-#define ack_edge_ioapic        ack_edge_ioapic_irq
-#define end_edge_ioapic        end_edge_ioapic_irq
-#endif
-
 #define APIC_MISMATCH_DEBUG
 
 #define IO_APIC_BASE(idx) \
@@ -202,13 +162,10 @@ extern int skip_ioapic_setup;
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
-extern int timer_uses_ioapic_pin_0;
 #endif
 
 extern int sis_apic_bug; /* dummy */ 
 
-extern int assign_irq_vector(int irq);
-
 void enable_NMI_through_LVT0 (void * dummy);
 
 extern spinlock_t i8259A_lock;
index 43469d8ab71a2534c91d4c80ccae2f0f3cae2563..5006c6e7565618fc0efc5918dc13e88d4833bf6c 100644 (file)
 
 #define FIRST_SYSTEM_VECTOR    0xef   /* duplicated in hw_irq.h */
 
-#ifdef CONFIG_PCI_MSI
-#define NR_IRQS FIRST_SYSTEM_VECTOR
+#define NR_IRQS (NR_VECTORS + (32 *NR_CPUS))
 #define NR_IRQ_VECTORS NR_IRQS
-#else
-#define NR_IRQS 224
-#define NR_IRQ_VECTORS (32 * NR_CPUS)
-#endif
 
 static __inline__ int irq_canonicalize(int irq)
 {
diff --git a/include/asm-x86_64/msi.h b/include/asm-x86_64/msi.h
deleted file mode 100644 (file)
index 3ad2346..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
- */
-
-#ifndef ASM_MSI_H
-#define ASM_MSI_H
-
-#include <asm/desc.h>
-#include <asm/mach_apic.h>
-#include <asm/smp.h>
-
-#define LAST_DEVICE_VECTOR     (FIRST_SYSTEM_VECTOR - 1)
-#define MSI_TARGET_CPU_SHIFT   12
-
-extern struct msi_ops msi_apic_ops;
-
-static inline int msi_arch_init(void)
-{
-       msi_register(&msi_apic_ops);
-       return 0;
-}
-
-#endif /* ASM_MSI_H */
diff --git a/include/asm-x86_64/msidef.h b/include/asm-x86_64/msidef.h
new file mode 100644 (file)
index 0000000..5b8acdd
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef ASM_MSIDEF_H
+#define ASM_MSIDEF_H
+
+/*
+ * Constants for Intel APIC based MSI messages.
+ */
+
+/*
+ * Shifts for MSI data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT          0
+#define  MSI_DATA_VECTOR_MASK          0x000000ff
+#define         MSI_DATA_VECTOR(v)             (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT   8
+#define  MSI_DATA_DELIVERY_FIXED       (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define  MSI_DATA_DELIVERY_LOWPRI      (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT           14
+#define         MSI_DATA_LEVEL_DEASSERT        (0 << MSI_DATA_LEVEL_SHIFT)
+#define         MSI_DATA_LEVEL_ASSERT          (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT         15
+#define  MSI_DATA_TRIGGER_EDGE         (0 << MSI_DATA_TRIGGER_SHIFT)
+#define  MSI_DATA_TRIGGER_LEVEL                (1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for msi address
+ */
+
+#define MSI_ADDR_BASE_HI               0
+#define MSI_ADDR_BASE_LO               0xfee00000
+
+#define MSI_ADDR_DEST_MODE_SHIFT       2
+#define  MSI_ADDR_DEST_MODE_PHYSICAL   (0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define         MSI_ADDR_DEST_MODE_LOGICAL     (1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT     3
+#define  MSI_ADDR_REDIRECTION_CPU      (0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
+#define  MSI_ADDR_REDIRECTION_LOWPRI   (1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */
+
+#define MSI_ADDR_DEST_ID_SHIFT         12
+#define         MSI_ADDR_DEST_ID_MASK          0x00ffff0
+#define  MSI_ADDR_DEST_ID(dest)                (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)
+
+#endif /* ASM_MSIDEF_H */
index 3be701dfe098166d789437802c61504cdb76d759..ffc4dcfd6ac1da332420b3a9928fa229d76293e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/addrspace.h
+ * include/asm-xtensa/a.out.h
  *
  * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
  * seems to depend on it.
index 5aae3f12407c63914fcca297948d5fd2e9368ae0..1e79c0e2746037379745c21533de616c70569a5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/cacheflush.h
+ * include/asm-xtensa/cache.h
  *
  * 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
index a91b96dc0efedfc7df47eab3f20402267d5ec22c..5093034723becd3df1ad1a7b2558097ad7230fb2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/cpextra.h
+ * include/asm-xtensa/coprocessor.h
  *
  * 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
index c425f10d086a500c9ca45ca63df857bef16e3f09..c39c91dfcc695a55e16933d60974310460987151 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/dma_mapping.h
+ * include/asm-xtensa/dma-mapping.h
  *
  * 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
index 3b89a772d0a0b954e5cec7647cdf0890f0db68c5..39e6f23921bba09de96d5b4bdb2c0f710322a25c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/ioctl.h
+ * include/asm-xtensa/ioctls.h
  *
  * 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
index a47cc734c20cceb8eb25203f2c5a97897116a26a..b4318934b10dfb0fd269bf7a5c918a19cad97d5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-xtensa/page.h
+ * linux/include/asm-xtensa/pgtable.h
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version2 as
index 44f0ae77b53909d768dd634f8b1a2a9db1147dc0..6916248295df6e021ab75d95fb20c482c0158149 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/asm-xtensa/processor.h
+ * include/asm-xtensa/siginfo.h
  *
  * 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
index f7a52e19b4bee532fd3fc988ac6421867e123a0f..7d564b6fc98f44a561d4afaf375d4e0f66eda11f 100644 (file)
@@ -156,12 +156,10 @@ header-y += toshiba.h
 header-y += ultrasound.h
 header-y += un.h
 header-y += utime.h
-header-y += utsname.h
 header-y += video_decoder.h
 header-y += video_encoder.h
 header-y += videotext.h
 header-y += vt.h
-header-y += wavefront.h
 header-y += wireless.h
 header-y += xattr.h
 header-y += x25.h
@@ -333,6 +331,7 @@ unifdef-y += unistd.h
 unifdef-y += usb_ch9.h
 unifdef-y += usbdevice_fs.h
 unifdef-y += user.h
+unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
 unifdef-y += wait.h
index 2ed2fd855133cba6d445a4babdb213e4eb4b2f75..22eb9367235aee14f2e2da4863f450d842287e2b 100644 (file)
@@ -331,8 +331,6 @@ extern int ac97_read_proc (char *page_out, char **start, off_t off,
 extern int ac97_probe_codec(struct ac97_codec *);
 extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
 extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
-extern int ac97_save_state(struct ac97_codec *codec);
-extern int ac97_restore_state(struct ac97_codec *codec);
 
 extern struct ac97_codec *ac97_alloc_codec(void);
 extern void ac97_release_codec(struct ac97_codec *codec);
@@ -346,9 +344,6 @@ struct ac97_driver {
        void (*remove) (struct ac97_codec *codec, struct ac97_driver *driver);
 };
 
-extern int ac97_register_driver(struct ac97_driver *driver);
-extern void ac97_unregister_driver(struct ac97_driver *driver);
-
 /* quirk types */
 enum {
        AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
index 3466b1d0ffd29ca6bbd8cbed53bac00e861cc94f..e3ca0a485cc646d171c7d1e5de1736b962908cdd 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/aio_abi.h
+/* include/linux/aio_abi.h
  *
  * Copyright 2000,2001,2002 Red Hat.
  *
index c3aa097518144c14556fef3e9998dbd3e5a46c69..b2ca666d9997ce35025fd85f57c655639bdab0d2 100644 (file)
@@ -75,7 +75,7 @@
 #define AUDIT_DAEMON_CONFIG     1203    /* Daemon config change */
 
 #define AUDIT_SYSCALL          1300    /* Syscall event */
-#define AUDIT_FS_WATCH         1301    /* Filesystem watch event */
+/* #define AUDIT_FS_WATCH      1301     * Deprecated */
 #define AUDIT_PATH             1302    /* Filename path information */
 #define AUDIT_IPC              1303    /* IPC record */
 #define AUDIT_SOCKETCALL       1304    /* sys_socketcall arguments */
@@ -88,6 +88,7 @@
 #define AUDIT_MQ_SENDRECV      1313    /* POSIX MQ send/receive record type */
 #define AUDIT_MQ_NOTIFY                1314    /* POSIX MQ notify record type */
 #define AUDIT_MQ_GETSETATTR    1315    /* POSIX MQ get/set attribute record type */
+#define AUDIT_KERNEL_OTHER     1316    /* For use by 3rd party modules */
 
 #define AUDIT_AVC              1400    /* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR      1401    /* Internal SE Linux Errors */
index 4bf9f33048e2aa22104b528e1f8c92e93e677e20..bf33f17bea997e4a1ef994e506817ff35d95658d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/awe_voice.h
+ * include/linux/awe_voice.h
  *
  * Voice information definitions for the low level driver for the 
  * AWE32/SB32/AWE64 wave table synth.
index 50d8b5744cf6fc5d7e5387289e7139e99cb557b3..612472aaa79c1607159794a2257356bde263e9a0 100644 (file)
 
 #ifndef HARDIRQ_BITS
 #define HARDIRQ_BITS   12
+
+#ifndef MAX_HARDIRQS_PER_CPU
+#define MAX_HARDIRQS_PER_CPU NR_IRQS
+#endif
+
 /*
  * The hardirq mask has to be large enough to have space for potentially
  * all IRQ sources in the system nesting on a single CPU.
  */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if (1 << HARDIRQ_BITS) < MAX_HARDIRQS_PER_CPU
 # error HARDIRQ_BITS is too low!
 #endif
 #endif
index 685b252e16cc1359fcfe30d42dd3cc549e60175b..efef11db790f2ce1cf4ddc7eb14a521c3af56464 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * asm-ppc/harrier_defs.h
+ * include/linux/harrier_defs.h
  *
  * Definitions for Motorola MCG Harrier North Bridge & Memory controller
  *
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
new file mode 100644 (file)
index 0000000..1f15ce2
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef LINUX_HTIRQ_H
+#define LINUX_HTIRQ_H
+
+/* Helper functions.. */
+void write_ht_irq_low(unsigned int irq, u32 data);
+void write_ht_irq_high(unsigned int irq, u32 data);
+u32  read_ht_irq_low(unsigned int irq);
+u32  read_ht_irq_high(unsigned int irq);
+void mask_ht_irq(unsigned int irq);
+void unmask_ht_irq(unsigned int irq);
+
+/* The arch hook for getting things started */
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
+
+#endif /* LINUX_HTIRQ_H */
index d9e2b3f36c35906ee1606a8a6aebce565c30214e..636094c29b167e185168d10882fd2c497903d166 100644 (file)
@@ -2,7 +2,6 @@
 #define _LINUX_IPC_H
 
 #include <linux/types.h>
-#include <linux/kref.h>
 
 #define IPC_PRIVATE ((__kernel_key_t) 0)  
 
@@ -52,6 +51,8 @@ struct ipc_perm
 
 #ifdef __KERNEL__
 
+#include <linux/kref.h>
+
 #define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
 
 /* used by in-kernel data structures */
index 48d3cb3b6a4737d380bdbe21e8be467284640bd1..6f463606c318ed46bbfdc0427f219023b1da3860 100644 (file)
@@ -59,6 +59,7 @@
 #define IRQ_NOAUTOEN           0x08000000      /* IRQ will not be enabled on request irq */
 #define IRQ_DELAYED_DISABLE    0x10000000      /* IRQ disable (masking) happens delayed. */
 #define IRQ_WAKEUP             0x20000000      /* IRQ triggers system wakeup */
+#define IRQ_MOVE_PENDING       0x40000000      /* need to re-target IRQ destination */
 
 struct proc_dir_entry;
 
@@ -132,7 +133,6 @@ struct irq_chip {
  * @affinity:          IRQ affinity on SMP
  * @cpu:               cpu index useful for balancing
  * @pending_mask:      pending rebalanced interrupts
- * @move_irq:          need to re-target IRQ destination
  * @dir:               /proc/irq/ procfs entry
  * @affinity_entry:    /proc/irq/smp_affinity procfs entry on SMP
  *
@@ -159,7 +159,6 @@ struct irq_desc {
 #endif
 #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
        cpumask_t               pending_mask;
-       unsigned int            move_irq;       /* need to re-target IRQ dest */
 #endif
 #ifdef CONFIG_PROC_FS
        struct proc_dir_entry *dir;
@@ -206,36 +205,7 @@ static inline void set_native_irq_info(int irq, cpumask_t mask)
 
 void set_pending_irq(unsigned int irq, cpumask_t mask);
 void move_native_irq(int irq);
-
-#ifdef CONFIG_PCI_MSI
-/*
- * Wonder why these are dummies?
- * For e.g the set_ioapic_affinity_vector() calls the set_ioapic_affinity_irq()
- * counter part after translating the vector to irq info. We need to perform
- * this operation on the real irq, when we dont use vector, i.e when
- * pci_use_vector() is false.
- */
-static inline void move_irq(int irq)
-{
-}
-
-static inline void set_irq_info(int irq, cpumask_t mask)
-{
-}
-
-#else /* CONFIG_PCI_MSI */
-
-static inline void move_irq(int irq)
-{
-       move_native_irq(irq);
-}
-
-static inline void set_irq_info(int irq, cpumask_t mask)
-{
-       set_native_irq_info(irq, mask);
-}
-
-#endif /* CONFIG_PCI_MSI */
+void move_masked_irq(int irq);
 
 #else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */
 
@@ -247,21 +217,20 @@ static inline void move_native_irq(int irq)
 {
 }
 
-static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
+static inline void move_masked_irq(int irq)
 {
 }
 
-static inline void set_irq_info(int irq, cpumask_t mask)
+static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
 {
-       set_native_irq_info(irq, mask);
 }
 
 #endif /* CONFIG_GENERIC_PENDING_IRQ */
 
 #else /* CONFIG_SMP */
 
-#define move_irq(x)
 #define move_native_irq(x)
+#define move_masked_irq(x)
 
 #endif /* CONFIG_SMP */
 
@@ -399,8 +368,22 @@ set_irq_chained_handler(unsigned int irq,
        __set_irq_handler(irq, handle, 1);
 }
 
-/* Set/get chip/data for an IRQ: */
+/* Handle dynamic irq creation and destruction */
+extern int create_irq(void);
+extern void destroy_irq(unsigned int irq);
 
+/* Test to see if a driver has successfully requested an irq */
+static inline int irq_has_action(unsigned int irq)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       return desc->action != NULL;
+}
+
+/* Dynamic irq helper functions */
+extern void dynamic_irq_init(unsigned int irq);
+extern void dynamic_irq_cleanup(unsigned int irq);
+
+/* Set/get chip/data for an IRQ: */
 extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
 extern int set_irq_data(unsigned int irq, void *data);
 extern int set_irq_chip_data(unsigned int irq, void *data);
index d6a3d4b345fc7b6f26dbd9c035178eabaf2120dd..d1af1dbeaeb4af7c0422943928e88dfdc42e824d 100644 (file)
@@ -109,6 +109,10 @@ static inline u32 ata_msg_init(int dval, int default_msg_enable_bits)
 #define ATA_TAG_POISON         0xfafbfcfdU
 
 /* move to PCI layer? */
+#define PCI_VDEVICE(vendor, device)            \
+       PCI_VENDOR_ID_##vendor, (device),       \
+       PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
 static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
 {
        return &pdev->dev;
@@ -138,8 +142,9 @@ enum {
        ATA_DFLAG_NCQ           = (1 << 3), /* device supports NCQ */
        ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
 
-       ATA_DFLAG_PIO           = (1 << 8), /* device currently in PIO mode */
-       ATA_DFLAG_SUSPENDED     = (1 << 9), /* device suspended */
+       ATA_DFLAG_PIO           = (1 << 8), /* device limited to PIO mode */
+       ATA_DFLAG_NCQ_OFF       = (1 << 9), /* devied limited to non-NCQ mode */
+       ATA_DFLAG_SUSPENDED     = (1 << 10), /* device suspended */
        ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 16),
index 47b7dbd647a63efa5e6c84b872231dc194d2c211..2909619c029589b5f74d86e236f12682cc4946f0 100644 (file)
  * Lockd host handle (used both by the client and server personality).
  */
 struct nlm_host {
-       struct nlm_host *       h_next;         /* linked list (hash table) */
+       struct hlist_node       h_hash;         /* doubly linked list */
        struct sockaddr_in      h_addr;         /* peer address */
        struct rpc_clnt *       h_rpcclnt;      /* RPC client to talk to peer */
-       char                    h_name[20];     /* remote hostname */
+       char *                  h_name;         /* remote hostname */
        u32                     h_version;      /* interface version */
        unsigned short          h_proto;        /* transport proto */
        unsigned short          h_reclaiming : 1,
                                h_server     : 1, /* server side, not client side */
-                               h_inuse      : 1,
-                               h_killed     : 1,
-                               h_monitored  : 1;
+                               h_inuse      : 1;
        wait_queue_head_t       h_gracewait;    /* wait while reclaiming */
        struct rw_semaphore     h_rwsem;        /* Reboot recovery lock */
        u32                     h_state;        /* pseudo-state counter */
@@ -61,6 +59,16 @@ struct nlm_host {
        spinlock_t              h_lock;
        struct list_head        h_granted;      /* Locks in GRANTED state */
        struct list_head        h_reclaim;      /* Locks in RECLAIM state */
+       struct nsm_handle *     h_nsmhandle;    /* NSM status handle */
+};
+
+struct nsm_handle {
+       struct list_head        sm_link;
+       atomic_t                sm_count;
+       char *                  sm_name;
+       struct sockaddr_in      sm_addr;
+       unsigned int            sm_monitored : 1,
+                               sm_sticky : 1;  /* don't unmonitor */
 };
 
 /*
@@ -96,15 +104,14 @@ struct nlm_rqst {
  * an NFS client.
  */
 struct nlm_file {
-       struct nlm_file *       f_next;         /* linked list */
+       struct hlist_node       f_list;         /* linked list */
        struct nfs_fh           f_handle;       /* NFS file handle */
        struct file *           f_file;         /* VFS file pointer */
        struct nlm_share *      f_shares;       /* DOS shares */
-       struct nlm_block *      f_blocks;       /* blocked locks */
+       struct list_head        f_blocks;       /* blocked locks */
        unsigned int            f_locks;        /* guesstimate # of locks */
        unsigned int            f_count;        /* reference count */
-       struct semaphore        f_sema;         /* avoid concurrent access */
-       int                     f_hash;         /* hash of f_handle */
+       struct mutex            f_mutex;        /* avoid concurrent access */
 };
 
 /*
@@ -114,25 +121,17 @@ struct nlm_file {
 #define NLM_NEVER              (~(unsigned long) 0)
 struct nlm_block {
        struct kref             b_count;        /* Reference count */
-       struct nlm_block *      b_next;         /* linked list (all blocks) */
-       struct nlm_block *      b_fnext;        /* linked list (per file) */
+       struct list_head        b_list;         /* linked list of all blocks */
+       struct list_head        b_flist;        /* linked list (per file) */
        struct nlm_rqst *       b_call;         /* RPC args & callback info */
        struct svc_serv *       b_daemon;       /* NLM service */
        struct nlm_host *       b_host;         /* host handle for RPC clnt */
        unsigned long           b_when;         /* next re-xmit */
        unsigned int            b_id;           /* block id */
-       unsigned char           b_queued;       /* re-queued */
        unsigned char           b_granted;      /* VFS granted lock */
        struct nlm_file *       b_file;         /* file in question */
 };
 
-/*
- * Valid actions for nlmsvc_traverse_files
- */
-#define NLM_ACT_CHECK          0               /* check for locks */
-#define NLM_ACT_MARK           1               /* mark & sweep */
-#define NLM_ACT_UNLOCK         2               /* release all locks */
-
 /*
  * Global variables
  */
@@ -143,6 +142,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
 #endif
 extern int                     nlmsvc_grace_period;
 extern unsigned long           nlmsvc_timeout;
+extern int                     nsm_use_hostnames;
 
 /*
  * Lockd client functions
@@ -155,22 +155,31 @@ struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock
 void             nlmclnt_finish_block(struct nlm_wait *block);
 int              nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
 u32              nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *);
-void             nlmclnt_recovery(struct nlm_host *, u32);
+void             nlmclnt_recovery(struct nlm_host *);
 int              nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
+void             nlmclnt_next_cookie(struct nlm_cookie *);
 
 /*
  * Host cache
  */
-struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *, int, int);
-struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *);
-struct nlm_host * nlm_lookup_host(int server, struct sockaddr_in *, int, int);
+struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *, int, int, const char *, int);
+struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *, const char *, int);
+struct nlm_host * nlm_lookup_host(int server, const struct sockaddr_in *, int, int, const char *, int);
 struct rpc_clnt * nlm_bind_host(struct nlm_host *);
 void             nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void             nlm_release_host(struct nlm_host *);
 void             nlm_shutdown_hosts(void);
-extern struct nlm_host *nlm_find_client(void);
+extern void      nlm_host_rebooted(const struct sockaddr_in *, const char *, int, u32);
+struct nsm_handle *nsm_find(const struct sockaddr_in *, const char *, int);
+void             nsm_release(struct nsm_handle *);
+
 
+/*
+ * This is used in garbage collection and resource reclaim
+ * A return value != 0 means destroy the lock/block/share
+ */
+typedef int      (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref);
 
 /*
  * Server-side lock handling
@@ -183,8 +192,8 @@ u32           nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
 u32              nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long    nlmsvc_retry_blocked(void);
 void             nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
-                                       int action);
-void     nlmsvc_grant_reply(struct svc_rqst *, struct nlm_cookie *, u32);
+                                       nlm_host_match_fn_t match);
+void             nlmsvc_grant_reply(struct nlm_cookie *, u32);
 
 /*
  * File handling for the server personality
index c75a424ebe4c81822f6e07e908068cce1f18bb36..cd7816e74c0536f71faf01e8cd909900efe48c5a 100644 (file)
@@ -25,6 +25,7 @@ u32   nlmsvc_share_file(struct nlm_host *, struct nlm_file *,
                                               struct nlm_args *);
 u32    nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *,
                                               struct nlm_args *);
-void   nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *, int);
+void   nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *,
+                                              nlm_host_match_fn_t);
 
 #endif /* LINUX_LOCKD_SHARE_H */
index 1080bb6ae3150ddd5c039216e7e3a5c314fceb34..fc61d40964dadfa24a585273fe1b660c31717f38 100644 (file)
@@ -28,7 +28,8 @@ struct nsm_args {
        u32             prog;           /* RPC callback info */
        u32             vers;
        u32             proc;
-       u32             proto;          /* protocol (udp/tcp) plus server/client flag */
+
+       char *          mon_name;
 };
 
 /*
@@ -41,6 +42,6 @@ struct nsm_res {
 
 int            nsm_monitor(struct nlm_host *);
 int            nsm_unmonitor(struct nlm_host *);
-extern u32     nsm_local_state;
+extern int     nsm_local_state;
 
 #endif /* LINUX_LOCKD_SM_INTER_H */
index cee36e7c0548f523752758eae748f482d28b4f42..3cc1ae25009b7e63d7f973311b94a600062b8e62 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/lockd/xdr.h
+ * linux/include/linux/lockd/xdr4.h
  *
  * XDR types for the NLM protocol
  *
diff --git a/include/linux/msi.h b/include/linux/msi.h
new file mode 100644 (file)
index 0000000..c7ef943
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef LINUX_MSI_H
+#define LINUX_MSI_H
+
+struct msi_msg {
+       u32     address_lo;     /* low 32 bits of msi message address */
+       u32     address_hi;     /* high 32 bits of msi message address */
+       u32     data;           /* 16 bits of msi message data */
+};
+
+/* Heper functions */
+extern void mask_msi_irq(unsigned int irq);
+extern void unmask_msi_irq(unsigned int irq);
+extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
+
+extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+
+struct msi_desc {
+       struct {
+               __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
+               __u8    maskbit : 1;    /* mask-pending bit supported ?   */
+               __u8    unused  : 1;
+               __u8    is_64   : 1;    /* Address size: 0=32bit 1=64bit  */
+               __u8    pos;            /* Location of the msi capability */
+               __u16   entry_nr;       /* specific enabled entry         */
+               unsigned default_irq;   /* default pre-assigned irq       */
+       }msi_attrib;
+
+       struct {
+               __u16   head;
+               __u16   tail;
+       }link;
+
+       void __iomem *mask_base;
+       struct pci_dev *dev;
+
+#ifdef CONFIG_PM
+       /* PM save area for MSIX address/data */
+       struct msi_msg msg_save;
+#endif
+};
+
+/*
+ * The arch hook for setup up msi irqs
+ */
+int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev);
+void arch_teardown_msi_irq(unsigned int irq);
+
+
+#endif /* LINUX_MSI_H */
index 2332eda07e0e1f71631774d57c61050b0400ebe3..9667863bd7e3c95496bf0cd0b47e1e589b5ed9ca 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/mtd/plat-ram.h
+/* linux/include/linux/mtd/plat-ram.h
  *
  * (c) 2004 Simtec Electronics
  *     http://www.simtec.co.uk/products/SWLINUX/
index b75bb1b38d09a244dcb46f569828424105dc3834..f0cc777905270822d4684c48447056ed4c073092 100644 (file)
 #define NFSSVC_MAXVERS         3
 
 /*
- * Maximum blocksize supported by daemon currently at 32K
+ * Maximum blocksizes supported by daemon under various circumstances.
  */
-#define NFSSVC_MAXBLKSIZE      (32*1024)
+#define NFSSVC_MAXBLKSIZE      RPCSVC_MAXPAYLOAD
+/* NFSv2 is limited by the protocol specification, see RFC 1094 */
+#define NFSSVC_MAXBLKSIZE_V2   (8*1024)
 
 #ifdef __KERNEL__
 
+#include <linux/sunrpc/msg_prot.h>
+
 #ifndef NFS_SUPER_MAGIC
 # define NFS_SUPER_MAGIC       0x6969
 #endif
 
-#define NFSD_BUFSIZE           (1024 + NFSSVC_MAXBLKSIZE)
+/*
+ * Largest number of bytes we need to allocate for an NFS
+ * call or reply.  Used to control buffer sizes.  We use
+ * the length of v3 WRITE, READDIR and READDIR replies
+ * which are an RPC header, up to 26 XDR units of reply
+ * data, and some page data.
+ *
+ * Note that accuracy here doesn't matter too much as the
+ * size is rounded up to a page size when allocating space.
+ */
+#define NFSD_BUFSIZE           ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE)
 
 #ifdef CONFIG_NFSD_V4
 # define NFSSVC_XDRSIZE                NFS4_SVC_XDRSIZE
index d2a8abb5011abfb8d5a2ad225672c6c35078dfc5..6e78ea969f4935977559495a1a0f139bc2423735 100644 (file)
 
 #ifdef __KERNEL__
 
+/*
+ * FS Locations
+ */
+
+#define MAX_FS_LOCATIONS       128
+
+struct nfsd4_fs_location {
+       char *hosts; /* colon separated list of hosts */
+       char *path;  /* slash separated list of path components */
+};
+
+struct nfsd4_fs_locations {
+       uint32_t locations_count;
+       struct nfsd4_fs_location *locations;
+/* If we're not actually serving this data ourselves (only providing a
+ * list of replicas that do serve it) then we set "migrated": */
+       int migrated;
+};
+
 struct svc_export {
        struct cache_head       h;
        struct auth_domain *    ex_client;
        int                     ex_flags;
        struct vfsmount *       ex_mnt;
        struct dentry *         ex_dentry;
+       char *                  ex_path;
        uid_t                   ex_anon_uid;
        gid_t                   ex_anon_gid;
        int                     ex_fsid;
+       struct nfsd4_fs_locations ex_fslocs;
 };
 
 /* an "export key" (expkey) maps a filehandlefragement to an
index e1dbc86c270b874e00ede638eeb8f64155d22872..d0d4aae7085fd5fea09de2831132ee3d0e80b734 100644 (file)
@@ -145,6 +145,7 @@ int nfsd_vers(int vers, enum vers_op change);
 void nfsd_reset_versions(void);
 int nfsd_create_serv(void);
 
+extern int nfsd_max_blksize;
 
 /* 
  * NFSv4 State
@@ -215,6 +216,7 @@ void                nfsd_lockd_shutdown(void);
 #define        nfserr_clid_inuse       __constant_htonl(NFSERR_CLID_INUSE)
 #define        nfserr_stale_clientid   __constant_htonl(NFSERR_STALE_CLIENTID)
 #define        nfserr_resource         __constant_htonl(NFSERR_RESOURCE)
+#define        nfserr_moved            __constant_htonl(NFSERR_MOVED)
 #define        nfserr_nofilehandle     __constant_htonl(NFSERR_NOFILEHANDLE)
 #define        nfserr_minor_vers_mismatch      __constant_htonl(NFSERR_MINOR_VERS_MISMATCH)
 #define nfserr_share_denied    __constant_htonl(NFSERR_SHARE_DENIED)
@@ -291,7 +293,6 @@ static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
 /*
  * The following attributes are currently not supported by the NFSv4 server:
  *    ARCHIVE       (deprecated anyway)
- *    FS_LOCATIONS  (will be supported eventually)
  *    HIDDEN        (unlikely to be supported any time soon)
  *    MIMETYPE      (unlikely to be supported any time soon)
  *    QUOTA_*       (will be supported in a forthcoming patch)
@@ -307,7 +308,7 @@ static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
  | FATTR4_WORD0_ACLSUPPORT      | FATTR4_WORD0_CANSETTIME   | FATTR4_WORD0_CASE_INSENSITIVE \
  | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED                             \
  | FATTR4_WORD0_FILEHANDLE      | FATTR4_WORD0_FILEID       | FATTR4_WORD0_FILES_AVAIL      \
- | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_HOMOGENEOUS      \
+ | FATTR4_WORD0_FILES_FREE      | FATTR4_WORD0_FILES_TOTAL  | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS      \
  | FATTR4_WORD0_MAXFILESIZE     | FATTR4_WORD0_MAXLINK      | FATTR4_WORD0_MAXNAME          \
  | FATTR4_WORD0_MAXREAD         | FATTR4_WORD0_MAXWRITE     | FATTR4_WORD0_ACL)
 
index 28a82fdd922f4d676a697cda557c2540a65a2b28..7678cfbe9960464d3bc2b3dd3011ff51fb8b863b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/nfsd/stats.h
+ * linux/include/linux/nfsd/stats.h
  *
  * Statistics for NFS server.
  *
index 3f4f7142bbe3920575017f2f42b8f443f06f30b7..0e53de87d886216f4f9478ce8bfde9c581b9c881 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/inxlude/linux/nfsd/xdr.h
+ * linux/include/linux/nfsd/xdr.h
  *
  * XDR types for nfsd. This is mainly a typing exercise.
  */
@@ -30,7 +30,6 @@ struct nfsd_readargs {
        struct svc_fh           fh;
        __u32                   offset;
        __u32                   count;
-       struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
 
@@ -38,7 +37,6 @@ struct nfsd_writeargs {
        svc_fh                  fh;
        __u32                   offset;
        int                     len;
-       struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
 
index a4322741f8b9d4ec85a80d8bbc69a04d401ba796..474d882dc2f385839a7b1cf869591a2f807a22f7 100644 (file)
@@ -33,7 +33,6 @@ struct nfsd3_readargs {
        struct svc_fh           fh;
        __u64                   offset;
        __u32                   count;
-       struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
 
@@ -43,7 +42,6 @@ struct nfsd3_writeargs {
        __u32                   count;
        int                     stable;
        __u32                   len;
-       struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
 
index 77adba7d228105fa1fd0f7fde49720814d92ca55..66e642762a0720e609ef0dcc09a648c511de7c43 100644 (file)
@@ -241,7 +241,6 @@ struct nfsd4_read {
        stateid_t       rd_stateid;         /* request */
        u64             rd_offset;          /* request */
        u32             rd_length;          /* request */
-       struct kvec     rd_iov[RPCSVC_MAXPAGES];
        int             rd_vlen;
        struct file     *rd_filp;
        
@@ -326,7 +325,6 @@ struct nfsd4_write {
        u64             wr_offset;          /* request */
        u32             wr_stable_how;      /* request */
        u32             wr_buflen;          /* request */
-       struct kvec     wr_vec[RPCSVC_MAXPAGES]; /* request */
        int             wr_vlen;
 
        u32             wr_bytes_written;   /* response */
index 7ff386a6ae87dd216e719dca52c39ce7aa12946f..10a43ed0527eb0215acba9078786105fb1f8b8de 100644 (file)
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/rwsem.h>
+#include <linux/srcu.h>
 
 /*
- * Notifier chains are of three types:
+ * Notifier chains are of four types:
  *
  *     Atomic notifier chains: Chain callbacks run in interrupt/atomic
  *             context. Callouts are not allowed to block.
  *     Raw notifier chains: There are no restrictions on callbacks,
  *             registration, or unregistration.  All locking and protection
  *             must be provided by the caller.
+ *     SRCU notifier chains: A variant of blocking notifier chains, with
+ *             the same restrictions.
  *
  * atomic_notifier_chain_register() may be called from an atomic context,
- * but blocking_notifier_chain_register() must be called from a process
- * context.  Ditto for the corresponding _unregister() routines.
+ * but blocking_notifier_chain_register() and srcu_notifier_chain_register()
+ * must be called from a process context.  Ditto for the corresponding
+ * _unregister() routines.
  *
- * atomic_notifier_chain_unregister() and blocking_notifier_chain_unregister()
- * _must not_ be called from within the call chain.
+ * atomic_notifier_chain_unregister(), blocking_notifier_chain_unregister(),
+ * and srcu_notifier_chain_unregister() _must not_ be called from within
+ * the call chain.
+ *
+ * SRCU notifier chains are an alternative form of blocking notifier chains.
+ * They use SRCU (Sleepable Read-Copy Update) instead of rw-semaphores for
+ * protection of the chain links.  This means there is _very_ low overhead
+ * in srcu_notifier_call_chain(): no cache bounces and no memory barriers.
+ * As compensation, srcu_notifier_chain_unregister() is rather expensive.
+ * SRCU notifier chains should be used when the chain will be called very
+ * often but notifier_blocks will seldom be removed.  Also, SRCU notifier
+ * chains are slightly more difficult to use because they require special
+ * runtime initialization.
  */
 
 struct notifier_block {
@@ -52,6 +67,12 @@ struct raw_notifier_head {
        struct notifier_block *head;
 };
 
+struct srcu_notifier_head {
+       struct mutex mutex;
+       struct srcu_struct srcu;
+       struct notifier_block *head;
+};
+
 #define ATOMIC_INIT_NOTIFIER_HEAD(name) do {   \
                spin_lock_init(&(name)->lock);  \
                (name)->head = NULL;            \
@@ -64,6 +85,11 @@ struct raw_notifier_head {
                (name)->head = NULL;            \
        } while (0)
 
+/* srcu_notifier_heads must be initialized and cleaned up dynamically */
+extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
+#define srcu_cleanup_notifier_head(name)       \
+               cleanup_srcu_struct(&(name)->srcu);
+
 #define ATOMIC_NOTIFIER_INIT(name) {                           \
                .lock = __SPIN_LOCK_UNLOCKED(name.lock),        \
                .head = NULL }
@@ -72,6 +98,7 @@ struct raw_notifier_head {
                .head = NULL }
 #define RAW_NOTIFIER_INIT(name)        {                               \
                .head = NULL }
+/* srcu_notifier_heads cannot be initialized statically */
 
 #define ATOMIC_NOTIFIER_HEAD(name)                             \
        struct atomic_notifier_head name =                      \
@@ -91,6 +118,8 @@ extern int blocking_notifier_chain_register(struct blocking_notifier_head *,
                struct notifier_block *);
 extern int raw_notifier_chain_register(struct raw_notifier_head *,
                struct notifier_block *);
+extern int srcu_notifier_chain_register(struct srcu_notifier_head *,
+               struct notifier_block *);
 
 extern int atomic_notifier_chain_unregister(struct atomic_notifier_head *,
                struct notifier_block *);
@@ -98,6 +127,8 @@ extern int blocking_notifier_chain_unregister(struct blocking_notifier_head *,
                struct notifier_block *);
 extern int raw_notifier_chain_unregister(struct raw_notifier_head *,
                struct notifier_block *);
+extern int srcu_notifier_chain_unregister(struct srcu_notifier_head *,
+               struct notifier_block *);
 
 extern int atomic_notifier_call_chain(struct atomic_notifier_head *,
                unsigned long val, void *v);
@@ -105,6 +136,8 @@ extern int blocking_notifier_call_chain(struct blocking_notifier_head *,
                unsigned long val, void *v);
 extern int raw_notifier_call_chain(struct raw_notifier_head *,
                unsigned long val, void *v);
+extern int srcu_notifier_call_chain(struct srcu_notifier_head *,
+               unsigned long val, void *v);
 
 #define NOTIFY_DONE            0x0000          /* Don't care */
 #define NOTIFY_OK              0x0001          /* Suits me */
index 4431ce4e1e6f9fa8d27801cb88a7f9c51049d572..5c604f5fad67d94c31ba6feb193eb49c0f42d0c8 100644 (file)
@@ -595,6 +595,7 @@ struct msix_entry {
        u16     entry;  /* driver uses to specify entry, OS writes */
 };
 
+
 #ifndef CONFIG_PCI_MSI
 static inline void pci_scan_msi_device(struct pci_dev *dev) {}
 static inline int pci_enable_msi(struct pci_dev *dev) {return -1;}
@@ -613,6 +614,12 @@ extern void pci_disable_msix(struct pci_dev *dev);
 extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
 #endif
 
+#ifdef CONFIG_HT_IRQ
+/* The functions a driver should call */
+int  ht_create_irq(struct pci_dev *dev, int idx);
+void ht_destroy_irq(unsigned int irq);
+#endif /* CONFIG_HT_IRQ */
+
 extern void pci_block_user_cfg_access(struct pci_dev *dev);
 extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
 
index 7d0e26cba42051d7230ec7d9ac1723c6569654ff..c312a12ad2d6729757892be98a20f194bac2c9a3 100644 (file)
  *     PCI Local Bus Specification
  *     PCI to PCI Bridge Specification
  *     PCI System Design Guide
+ *
+ *     For hypertransport information, please consult the following manuals
+ *     from http://www.hypertransport.org
+ *
+ *     The Hypertransport I/O Link Specification
  */
 
 #ifndef LINUX_PCI_REGS_H
 #define PCI_PWR_CAP            12      /* Capability */
 #define  PCI_PWR_CAP_BUDGET(x) ((x) & 1)       /* Included in system budget */
 
+/* Hypertransport sub capability types */
+#define HT_CAPTYPE_SLAVE       0x00    /* Slave/Primary link configuration */
+#define HT_CAPTYPE_HOST                0x20    /* Host/Secondary link configuration */
+#define HT_CAPTYPE_IRQ         0x80    /* IRQ Configuration */
+#define HT_CAPTYPE_REMAPPING_40        0xA0    /* 40 bit address remapping */
+#define HT_CAPTYPE_REMAPPING_64 0xA2   /* 64 bit address remapping */
+#define HT_CAPTYPE_UNITID_CLUMP        0x90    /* Unit ID clumping */
+#define HT_CAPTYPE_EXTCONF     0x98    /* Extended Configuration Space Access */
+#define HT_CAPTYPE_MSI_MAPPING 0xA8    /* MSI Mapping Capability */
+#define HT_CAPTYPE_DIRECT_ROUTE        0xB0    /* Direct routing configuration */
+#define HT_CAPTYPE_VCSET       0xB8    /* Virtual Channel configuration */
+#define HT_CAPTYPE_ERROR_RETRY 0xC0    /* Retry on error configuration */
+#define HT_CAPTYPE_GEN3                0xD0    /* Generation 3 hypertransport configuration */
+#define HT_CAPTYPE_PM          0xE0    /* Hypertransport powermanagement configuration */
+
+
 #endif /* LINUX_PCI_REGS_H */
index f376a7598a782139affd060cd36323df7306c54d..dc18c5d23ebe4086518512ca8bb2cd8dfd8157bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/char/ppdev.h
+ * linux/include/linux/ppdev.h
  *
  * User-space parallel port device driver (header file).
  *
index b4ca73d65891ba8b60ba24d1fe2e0adca745911a..c6b7485eac7ce1e59c7f01cf71221e6637f524ce 100644 (file)
@@ -19,7 +19,7 @@
  *
  * Author: Dipankar Sarma <dipankar@in.ibm.com>
  * 
- * Based on the original work by Paul McKenney <paul.mckenney@us.ibm.com>
+ * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  * Papers:
  * http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf
@@ -66,6 +66,8 @@ struct rcu_ctrlblk {
        long    completed;      /* Number of the last completed batch         */
        int     next_pending;   /* Is the next batch already waiting?         */
 
+       int     signaled;
+
        spinlock_t      lock    ____cacheline_internodealigned_in_smp;
        cpumask_t       cpumask; /* CPUs that need to switch in order    */
                                 /* for current batch to proceed.        */
@@ -106,9 +108,6 @@ struct rcu_data {
        long            blimit;          /* Upper limit on a processed batch */
        int cpu;
        struct rcu_head barrier;
-#ifdef CONFIG_SMP
-       long            last_rs_qlen;    /* qlen during the last resched */
-#endif
 };
 
 DECLARE_PER_CPU(struct rcu_data, rcu_data);
index 693c0557e70bdf6b13baa898a4dca5c82b8ae919..de466e11e271a92df49206d317a5ce6572f3d6af 100644 (file)
@@ -32,7 +32,7 @@ extern unsigned scx200_cb_base;
 
 /* High Resolution Timer */
 #define SCx200_TIMER_OFFSET 0x08
-#define SCx200_TIMER_SIZE 0x05
+#define SCx200_TIMER_SIZE 0x06
 
 /* Clock Generators */
 #define SCx200_CLOCKGEN_OFFSET 0x10
index a96fd9310d55a7dc89176db3cdb4bc7c1ba26950..c4947b8a2c0333f00a520fb83db5b77a725e09fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/mm/slab.h
+ * linux/include/linux/slab.h
  * Written by Mark Hemment, 1996.
  * (markhe@nextd.demon.co.uk)
  */
@@ -77,13 +77,6 @@ struct cache_sizes {
 extern struct cache_sizes malloc_sizes[];
 
 extern void *__kmalloc(size_t, gfp_t);
-#ifndef CONFIG_DEBUG_SLAB
-#define ____kmalloc(size, flags) __kmalloc(size, flags)
-#else
-extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
-#define ____kmalloc(size, flags) \
-    __kmalloc_track_caller(size, flags, __builtin_return_address(0))
-#endif
 
 /**
  * kmalloc - allocate memory
@@ -153,6 +146,23 @@ found:
        return __kmalloc(size, flags);
 }
 
+/*
+ * kmalloc_track_caller is a special version of kmalloc that records the
+ * calling function of the routine calling it for slab leak tracking instead
+ * of just the calling function (confusing, eh?).
+ * It's useful when the call to kmalloc comes from a widely-used standard
+ * allocator where we care about the real place the memory allocation
+ * request comes from.
+ */
+#ifndef CONFIG_DEBUG_SLAB
+#define kmalloc_track_caller(size, flags) \
+       __kmalloc(size, flags)
+#else
+extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
+#define kmalloc_track_caller(size, flags) \
+       __kmalloc_track_caller(size, flags, __builtin_return_address(0))
+#endif
+
 extern void *__kzalloc(size_t, gfp_t);
 
 /**
@@ -271,7 +281,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
 #define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
 #define kmalloc_node(s, f, n) kmalloc(s, f)
 #define kzalloc(s, f) __kzalloc(s, f)
-#define ____kmalloc kmalloc
+#define kmalloc_track_caller kmalloc
 
 #endif /* CONFIG_SLOB */
 
index f63d8342ffa342a813c5b2bc10f89a54f00f801a..9e2a94feed6baa519190de1db4521b4eaeeead43 100644 (file)
@@ -35,10 +35,8 @@ extern int register_sound_special_device(const struct file_operations *fops, int
 extern int register_sound_mixer(const struct file_operations *fops, int dev);
 extern int register_sound_midi(const struct file_operations *fops, int dev);
 extern int register_sound_dsp(const struct file_operations *fops, int dev);
-extern int register_sound_synth(const struct file_operations *fops, int dev);
 
 extern void unregister_sound_special(int unit);
 extern void unregister_sound_mixer(int unit);
 extern void unregister_sound_midi(int unit);
 extern void unregister_sound_dsp(int unit);
-extern void unregister_sound_synth(int unit);
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
new file mode 100644 (file)
index 0000000..aca0eee
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Sleepable Read-Copy Update mechanism for mutual exclusion
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Paul McKenney <paulmck@us.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU/ *.txt
+ *
+ */
+
+#ifndef _LINUX_SRCU_H
+#define _LINUX_SRCU_H
+
+struct srcu_struct_array {
+       int c[2];
+};
+
+struct srcu_struct {
+       int completed;
+       struct srcu_struct_array *per_cpu_ref;
+       struct mutex mutex;
+};
+
+#ifndef CONFIG_PREEMPT
+#define srcu_barrier() barrier()
+#else /* #ifndef CONFIG_PREEMPT */
+#define srcu_barrier()
+#endif /* #else #ifndef CONFIG_PREEMPT */
+
+int init_srcu_struct(struct srcu_struct *sp);
+void cleanup_srcu_struct(struct srcu_struct *sp);
+int srcu_read_lock(struct srcu_struct *sp) __acquires(sp);
+void srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp);
+void synchronize_srcu(struct srcu_struct *sp);
+long srcu_batches_completed(struct srcu_struct *sp);
+
+#endif
index 862c0d8c83817ce2288dd5cd79f5d46ed7557654..534cdc7be58dbbef6350ddef8fd89983bb7f6e41 100644 (file)
@@ -20,9 +20,6 @@
 /* size of the nodename buffer */
 #define UNX_MAXNODENAME        32
 
-/* Maximum size (in bytes) of an rpc credential or verifier */
-#define RPC_MAX_AUTH_SIZE (400)
-
 /* Work around the lack of a VFS credential */
 struct auth_cred {
        uid_t   uid;
index 03084dc4bb6a42decf3cb57b5eca37d21107e2b4..97b62e97dd8d3fcaef89e0332005d97abd397c5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/auth_gss.h
+ * linux/include/linux/sunrpc/auth_gss.h
  *
  * Declarations for RPCSEC_GSS
  *
index b5612c958ccef64d5437ca3f89dd7dd425023d58..3699dff7db8fd3c129488745f9e851d7abbf56e1 100644 (file)
@@ -163,6 +163,17 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
        kref_put(&h->ref, cd->cache_put);
 }
 
+static inline int cache_valid(struct cache_head *h)
+{
+       /* If an item has been unhashed pending removal when
+        * the refcount drops to 0, the expiry_time will be
+        * set to 0.  We don't want to consider such items
+        * valid in this context even though CACHE_VALID is
+        * set.
+        */
+       return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags));
+}
+
 extern int cache_check(struct cache_detail *detail,
                       struct cache_head *h, struct cache_req *rqstp);
 extern void cache_flush(void);
index 6e112cc5cdda9928c948a26f8e3001c6687cd5ca..5eca9e442051310525162222c9891776be778d9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/gss_api.h
+ * linux/include/linux/sunrpc/gss_api.h
  *
  * Somewhat simplified version of the gss api.
  *
index d9f5934ac9fedbbe789fe0da125ac89b979c13b7..1e65f2dd80e5d5aa4bbd8f5a7885862cccfe5c4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/net/sunrpc/msg_prot.h
+ * linux/include/linux/sunrpc/msg_prot.h
  *
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
@@ -11,6 +11,9 @@
 
 #define RPC_VERSION 2
 
+/* size of an XDR encoding unit in bytes, i.e. 32bit */
+#define XDR_UNIT       (4)
+
 /* spec defines authentication flavor as an unsigned 32 bit integer */
 typedef u32    rpc_authflavor_t;
 
@@ -34,6 +37,9 @@ enum rpc_auth_flavors {
        RPC_AUTH_GSS_SPKMP = 390011,
 };
 
+/* Maximum size (in bytes) of an rpc credential or verifier */
+#define RPC_MAX_AUTH_SIZE (400)
+
 enum rpc_msg_type {
        RPC_CALL = 0,
        RPC_REPLY = 1
@@ -101,5 +107,39 @@ typedef __be32     rpc_fraghdr;
 #define        RPC_FRAGMENT_SIZE_MASK          (~RPC_LAST_STREAM_FRAGMENT)
 #define        RPC_MAX_FRAGMENT_SIZE           ((1U << 31) - 1)
 
+/*
+ * RPC call and reply header size as number of 32bit words (verifier
+ * size computed separately, see below)
+ */
+#define RPC_CALLHDRSIZE                (6)
+#define RPC_REPHDRSIZE         (4)
+
+
+/*
+ * Maximum RPC header size, including authentication,
+ * as number of 32bit words (see RFCs 1831, 1832).
+ *
+ *     xid                         1 xdr unit = 4 bytes
+ *     mtype                       1
+ *     rpc_version                 1
+ *     program                     1
+ *     prog_version                1
+ *     procedure                   1
+ *     cred {
+ *         flavor                  1
+ *         length                  1
+ *         body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
+ *     }
+ *     verf {
+ *         flavor                  1
+ *         length                  1
+ *         body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
+ *     }
+ *     TOTAL                       210 xdr units = 840 bytes
+ */
+#define RPC_MAX_HEADER_WITH_AUTH \
+       (RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
+
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_MSGPROT_H_ */
index 4ebcdf91f3b3dcc078e7fadf6313dd23dc4175fa..d6288e89fd9d64308113cc0035afd29ea1f71528 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/in.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/svcauth.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
@@ -95,8 +96,28 @@ static inline void svc_get(struct svc_serv *serv)
  * Maximum payload size supported by a kernel RPC server.
  * This is use to determine the max number of pages nfsd is
  * willing to return in a single READ operation.
+ *
+ * These happen to all be powers of 2, which is not strictly
+ * necessary but helps enforce the real limitation, which is
+ * that they should be multiples of PAGE_CACHE_SIZE.
+ *
+ * For UDP transports, a block plus NFS,RPC, and UDP headers
+ * has to fit into the IP datagram limit of 64K.  The largest
+ * feasible number for all known page sizes is probably 48K,
+ * but we choose 32K here.  This is the same as the historical
+ * Linux limit; someone who cares more about NFS/UDP performance
+ * can test a larger number.
+ *
+ * For TCP transports we have more freedom.  A size of 1MB is
+ * chosen to match the client limit.  Other OSes are known to
+ * have larger limits, but those numbers are probably beyond
+ * the point of diminishing returns.
  */
-#define RPCSVC_MAXPAYLOAD      (64*1024u)
+#define RPCSVC_MAXPAYLOAD      (1*1024*1024u)
+#define RPCSVC_MAXPAYLOAD_TCP  RPCSVC_MAXPAYLOAD
+#define RPCSVC_MAXPAYLOAD_UDP  (32*1024u)
+
+extern u32 svc_max_payload(const struct svc_rqst *rqstp);
 
 /*
  * RPC Requsts and replies are stored in one or more pages.
@@ -170,7 +191,6 @@ static inline void svc_putu32(struct kvec *iov, __be32 val)
 /*
  * The context of a single thread, including the request currently being
  * processed.
- * NOTE: First two items must be prev/next.
  */
 struct svc_rqst {
        struct list_head        rq_list;        /* idle list */
@@ -189,12 +209,11 @@ struct svc_rqst {
 
        struct xdr_buf          rq_arg;
        struct xdr_buf          rq_res;
-       struct page *           rq_argpages[RPCSVC_MAXPAGES];
-       struct page *           rq_respages[RPCSVC_MAXPAGES];
-       int                     rq_restailpage;
-       short                   rq_argused;     /* pages used for argument */
-       short                   rq_arghi;       /* pages available in argument page list */
-       short                   rq_resused;     /* pages used for result */
+       struct page *           rq_pages[RPCSVC_MAXPAGES];
+       struct page *           *rq_respages;   /* points into rq_pages */
+       int                     rq_resused;     /* number of pages used for result */
+
+       struct kvec             rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
 
        __be32                  rq_xid;         /* transmission id */
        u32                     rq_prog;        /* program number */
@@ -255,63 +274,18 @@ xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
        return vec->iov_len <= PAGE_SIZE;
 }
 
-static inline struct page *
-svc_take_res_page(struct svc_rqst *rqstp)
-{
-       if (rqstp->rq_arghi <= rqstp->rq_argused)
-               return NULL;
-       rqstp->rq_arghi--;
-       rqstp->rq_respages[rqstp->rq_resused] =
-               rqstp->rq_argpages[rqstp->rq_arghi];
-       return rqstp->rq_respages[rqstp->rq_resused++];
-}
-
-static inline void svc_take_page(struct svc_rqst *rqstp)
-{
-       if (rqstp->rq_arghi <= rqstp->rq_argused) {
-               WARN_ON(1);
-               return;
-       }
-       rqstp->rq_arghi--;
-       rqstp->rq_respages[rqstp->rq_resused] =
-               rqstp->rq_argpages[rqstp->rq_arghi];
-       rqstp->rq_resused++;
-}
-
-static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
-{
-        while (rqstp->rq_resused) {
-               if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-                       continue;
-               rqstp->rq_argpages[rqstp->rq_arghi++] =
-                       rqstp->rq_respages[rqstp->rq_resused];
-               rqstp->rq_respages[rqstp->rq_resused] = NULL;
-       }
-}
-
-static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
+static inline void svc_free_res_pages(struct svc_rqst *rqstp)
 {
-       while (rqstp->rq_resused &&
-              rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
-
-               if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
-                       rqstp->rq_argpages[rqstp->rq_arghi++] =
-                               rqstp->rq_respages[rqstp->rq_resused];
-                       rqstp->rq_respages[rqstp->rq_resused] = NULL;
+       while (rqstp->rq_resused) {
+               struct page **pp = (rqstp->rq_respages +
+                                   --rqstp->rq_resused);
+               if (*pp) {
+                       put_page(*pp);
+                       *pp = NULL;
                }
        }
 }
 
-static inline void svc_free_allpages(struct svc_rqst *rqstp)
-{
-        while (rqstp->rq_resused) {
-               if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-                       continue;
-               put_page(rqstp->rq_respages[rqstp->rq_resused]);
-               rqstp->rq_respages[rqstp->rq_resused] = NULL;
-       }
-}
-
 struct svc_deferred_req {
        u32                     prot;   /* protocol (UDP or TCP) */
        struct sockaddr_in      addr;
@@ -347,6 +321,9 @@ struct svc_version {
        struct svc_procedure *  vs_proc;        /* per-procedure info */
        u32                     vs_xdrsize;     /* xdrsize needed for this version */
 
+       unsigned int            vs_hidden : 1;  /* Don't register with portmapper.
+                                                * Only used for nfsacl so far. */
+
        /* Override dispatch function (e.g. when caching replies).
         * A return value of 0 means drop the request. 
         * vs_dispatch == NULL means use default dispatcher.
index a6601650deeb4ef4131a319e4757bcadb313e0b1..de92619b0826066f7809c1ef264a029e0a7b84d2 100644 (file)
@@ -126,6 +126,7 @@ extern struct auth_domain *auth_domain_find(char *name);
 extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
 extern int auth_unix_forget_old(struct auth_domain *dom);
 extern void svcauth_unix_purge(void);
+extern void svcauth_unix_info_release(void *);
 
 static inline unsigned long hash_str(char *name, int bits)
 {
index 3a2206f61de0697061d158238ebb9bcf91f6c16b..5a5db16ab6607b046b2ae5c9eccca2a095400317 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/linux/svcauth_gss.h
+ * linux/include/linux/sunrpc/svcauth_gss.h
  *
  * Bruce Fields <bfields@umich.edu>
  * Copyright (c) 2002 The Regents of the Unviersity of Michigan
index 4c296152cbfa71ecdb52efb98e2586454a9b1e30..98b21ad370fdd529c7a35105642276876360ff82 100644 (file)
@@ -54,6 +54,9 @@ struct svc_sock {
        int                     sk_reclen;      /* length of record */
        int                     sk_tcplen;      /* current read length */
        time_t                  sk_lastrecv;    /* time of last received request */
+
+       /* cache of various info for TCP sockets */
+       void                    *sk_info_authunix;
 };
 
 /*
index 6cf6265807529842e10b3b0553bb8d401d17e84a..60394fbc4c704d62d05325c119f66da040416291 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kref.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/msg_prot.h>
 
 extern unsigned int xprt_udp_slot_table_entries;
 extern unsigned int xprt_tcp_slot_table_entries;
@@ -23,13 +24,6 @@ extern unsigned int xprt_tcp_slot_table_entries;
 #define RPC_DEF_SLOT_TABLE     (16U)
 #define RPC_MAX_SLOT_TABLE     (128U)
 
-/*
- * RPC call and reply header size as number of 32bit words (verifier
- * size computed separately)
- */
-#define RPC_CALLHDRSIZE                6
-#define RPC_REPHDRSIZE         4
-
 /*
  * Parameters for choosing a free port
  */
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
new file mode 100644 (file)
index 0000000..203dd5e
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  tifm.h - TI FlashMedia driver
+ *
+ *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
+ *
+ * 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 _TIFM_H
+#define _TIFM_H
+
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+/* Host registers (relative to pci base address): */
+enum {
+       FM_SET_INTERRUPT_ENABLE   = 0x008,
+       FM_CLEAR_INTERRUPT_ENABLE = 0x00c,
+       FM_INTERRUPT_STATUS       = 0x014 };
+
+/* Socket registers (relative to socket base address): */
+enum {
+       SOCK_CONTROL                   = 0x004,
+       SOCK_PRESENT_STATE             = 0x008,
+       SOCK_DMA_ADDRESS               = 0x00c,
+       SOCK_DMA_CONTROL               = 0x010,
+       SOCK_DMA_FIFO_INT_ENABLE_SET   = 0x014,
+       SOCK_DMA_FIFO_INT_ENABLE_CLEAR = 0x018,
+       SOCK_DMA_FIFO_STATUS           = 0x020,
+       SOCK_FIFO_CONTROL              = 0x024,
+       SOCK_FIFO_PAGE_SIZE            = 0x028,
+       SOCK_MMCSD_COMMAND             = 0x104,
+       SOCK_MMCSD_ARG_LOW             = 0x108,
+       SOCK_MMCSD_ARG_HIGH            = 0x10c,
+       SOCK_MMCSD_CONFIG              = 0x110,
+       SOCK_MMCSD_STATUS              = 0x114,
+       SOCK_MMCSD_INT_ENABLE          = 0x118,
+       SOCK_MMCSD_COMMAND_TO          = 0x11c,
+       SOCK_MMCSD_DATA_TO             = 0x120,
+       SOCK_MMCSD_DATA                = 0x124,
+       SOCK_MMCSD_BLOCK_LEN           = 0x128,
+       SOCK_MMCSD_NUM_BLOCKS          = 0x12c,
+       SOCK_MMCSD_BUFFER_CONFIG       = 0x130,
+       SOCK_MMCSD_SPI_CONFIG          = 0x134,
+       SOCK_MMCSD_SDIO_MODE_CONFIG    = 0x138,
+       SOCK_MMCSD_RESPONSE            = 0x144,
+       SOCK_MMCSD_SDIO_SR             = 0x164,
+       SOCK_MMCSD_SYSTEM_CONTROL      = 0x168,
+       SOCK_MMCSD_SYSTEM_STATUS       = 0x16c,
+       SOCK_MS_COMMAND                = 0x184,
+       SOCK_MS_DATA                   = 0x188,
+       SOCK_MS_STATUS                 = 0x18c,
+       SOCK_MS_SYSTEM                 = 0x190,
+       SOCK_FIFO_ACCESS               = 0x200 };
+
+
+#define TIFM_IRQ_ENABLE           0x80000000
+#define TIFM_IRQ_SOCKMASK         0x00000001
+#define TIFM_IRQ_CARDMASK         0x00000100
+#define TIFM_IRQ_FIFOMASK         0x00010000
+#define TIFM_IRQ_SETALL           0xffffffff
+#define TIFM_IRQ_SETALLSOCK       0x0000000f
+
+#define TIFM_CTRL_LED             0x00000040
+#define TIFM_CTRL_FAST_CLK        0x00000100
+
+#define TIFM_SOCK_STATE_OCCUPIED  0x00000008
+#define TIFM_SOCK_STATE_POWERED   0x00000080
+
+#define TIFM_FIFO_ENABLE          0x00000001 /* Meaning of this constant is unverified */
+#define TIFM_FIFO_INT_SETALL      0x0000ffff
+#define TIFM_FIFO_INTMASK         0x00000005 /* Meaning of this constant is unverified */
+
+#define TIFM_DMA_RESET            0x00000002 /* Meaning of this constant is unverified */
+#define TIFM_DMA_TX               0x00008000 /* Meaning of this constant is unverified */
+#define TIFM_DMA_EN               0x00000001 /* Meaning of this constant is unverified */
+
+typedef enum {FM_NULL = 0, FM_XD = 0x01, FM_MS = 0x02, FM_SD = 0x03} tifm_media_id;
+
+struct tifm_driver;
+struct tifm_dev {
+       char __iomem            *addr;
+       spinlock_t              lock;
+       tifm_media_id           media_id;
+       char                    wq_name[KOBJ_NAME_LEN];
+       struct workqueue_struct *wq;
+
+       unsigned int            (*signal_irq)(struct tifm_dev *sock,
+                                             unsigned int sock_irq_status);
+
+       struct tifm_driver      *drv;
+       struct device           dev;
+};
+
+struct tifm_driver {
+       tifm_media_id        *id_table;
+       int                  (*probe)(struct tifm_dev *dev);
+       void                 (*remove)(struct tifm_dev *dev);
+
+       struct device_driver driver;
+};
+
+struct tifm_adapter {
+       char __iomem            *addr;
+       unsigned int            irq_status;
+       unsigned int            insert_mask;
+       unsigned int            remove_mask;
+       spinlock_t              lock;
+       unsigned int            id;
+       unsigned int            max_sockets;
+       char                    wq_name[KOBJ_NAME_LEN];
+       unsigned int            inhibit_new_cards;
+       struct workqueue_struct *wq;
+       struct work_struct      media_inserter;
+       struct work_struct      media_remover;
+       struct tifm_dev         **sockets;
+       struct class_device     cdev;
+       struct device           *dev;
+
+       void                    (*eject)(struct tifm_adapter *fm, struct tifm_dev *sock);
+};
+
+struct tifm_adapter *tifm_alloc_adapter(void);
+void tifm_free_device(struct device *dev);
+void tifm_free_adapter(struct tifm_adapter *fm);
+int tifm_add_adapter(struct tifm_adapter *fm);
+void tifm_remove_adapter(struct tifm_adapter *fm);
+struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id);
+int tifm_register_driver(struct tifm_driver *drv);
+void tifm_unregister_driver(struct tifm_driver *drv);
+void tifm_eject(struct tifm_dev *sock);
+int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+               int direction);
+void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
+                  int direction);
+
+
+static inline void *tifm_get_drvdata(struct tifm_dev *dev)
+{
+        return dev_get_drvdata(&dev->dev);
+}
+
+static inline void tifm_set_drvdata(struct tifm_dev *dev, void *data)
+{
+       dev_set_drvdata(&dev->dev, data);
+}
+
+struct tifm_device_id {
+       tifm_media_id media_id;
+};
+
+#endif
index 02e4b69720645e5a15a04b8f74d0a78b69638b00..a4555fe3754cdb639775d5152307692d186a1151 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef _LINUX_UTSNAME_H
 #define _LINUX_UTSNAME_H
 
-#include <linux/sched.h>
-#include <linux/kref.h>
-#include <linux/nsproxy.h>
-#include <asm/atomic.h>
-
 #define __OLD_UTS_LEN 8
 
 struct oldold_utsname {
@@ -35,6 +30,13 @@ struct new_utsname {
        char domainname[65];
 };
 
+#ifdef __KERNEL__
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/nsproxy.h>
+#include <asm/atomic.h>
+
 struct uts_namespace {
        struct kref kref;
        struct new_utsname name;
@@ -86,4 +88,7 @@ static inline struct new_utsname *init_utsname(void)
 }
 
 extern struct rw_semaphore uts_sem;
-#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_UTSNAME_H */
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
deleted file mode 100644 (file)
index 51ab3c9..0000000
+++ /dev/null
@@ -1,675 +0,0 @@
-#ifndef __wavefront_h__
-#define __wavefront_h__
-
-/* WaveFront header file.
- *   
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.  
- */
-
-#if (!defined(__GNUC__) && !defined(__GNUG__))
-
-     You will not be able to compile this file correctly without gcc, because
-     it is necessary to pack the "wavefront_alias" structure to a size
-     of 22 bytes, corresponding to 16-bit alignment (as would have been
-     the case on the original platform, MS-DOS). If this is not done,
-     then WavePatch-format files cannot be read/written correctly.
-     The method used to do this here ("__attribute__((packed)") is
-     completely compiler dependent.
-     
-     All other wavefront_* types end up aligned to 32 bit values and
-     still have the same (correct) size.
-
-#else
-
-     /* However, note that as of G++ 2.7.3.2, g++ was unable to
-       correctly parse *type* __attribute__ tags. It will do the
-       right thing if we use the "packed" attribute on each struct
-       member, which has the same semantics anyway. 
-     */
-
-#endif /* __GNUC__ */
-
-/***************************** WARNING ********************************
-  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO 
-  BE USED WITH EITHER C *OR* C++.
- **********************************************************************/
-
-#ifndef NUM_MIDIKEYS 
-#define NUM_MIDIKEYS 128
-#endif  /* NUM_MIDIKEYS */
-
-#ifndef NUM_MIDICHANNELS
-#define NUM_MIDICHANNELS 16
-#endif  /* NUM_MIDICHANNELS */
-
-/* These are very useful/important. the original wavefront interface
-   was developed on a 16 bit system, where sizeof(int) = 2
-   bytes. Defining things like this makes the code much more portable, and
-   easier to understand without having to toggle back and forth
-   between a 16-bit view of the world and a 32-bit one. 
- */   
-
-typedef short INT16;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef char CHAR8;
-typedef unsigned char UCHAR8;
-
-/* Pseudo-commands not part of the WaveFront command set.
-   These are used for various driver controls and direct
-   hardware control.
- */
-
-#define WFC_DEBUG_DRIVER                0
-#define WFC_FX_IOCTL                    1
-#define WFC_PATCH_STATUS                2
-#define WFC_PROGRAM_STATUS              3
-#define WFC_SAMPLE_STATUS               4
-#define WFC_DISABLE_INTERRUPTS          5
-#define WFC_ENABLE_INTERRUPTS           6
-#define WFC_INTERRUPT_STATUS            7
-#define WFC_ROMSAMPLES_RDONLY           8
-#define WFC_IDENTIFY_SLOT_TYPE          9
-
-/* Wavefront synth commands
- */
-
-#define WFC_DOWNLOAD_SAMPLE            0x80
-#define WFC_DOWNLOAD_BLOCK             0x81
-#define WFC_DOWNLOAD_MULTISAMPLE       0x82
-#define WFC_DOWNLOAD_SAMPLE_ALIAS      0x83
-#define WFC_DELETE_SAMPLE              0x84
-#define WFC_REPORT_FREE_MEMORY         0x85
-#define WFC_DOWNLOAD_PATCH             0x86
-#define WFC_DOWNLOAD_PROGRAM           0x87
-#define WFC_SET_SYNTHVOL               0x89
-#define WFC_SET_NVOICES                        0x8B
-#define WFC_DOWNLOAD_DRUM              0x90
-#define WFC_GET_SYNTHVOL               0x92
-#define WFC_GET_NVOICES                        0x94
-#define WFC_DISABLE_CHANNEL            0x9A
-#define WFC_ENABLE_CHANNEL             0x9B
-#define WFC_MISYNTH_OFF                        0x9D
-#define WFC_MISYNTH_ON                 0x9E
-#define WFC_FIRMWARE_VERSION           0x9F
-#define WFC_GET_NSAMPLES               0xA0
-#define WFC_DISABLE_DRUM_PROGRAM       0xA2
-#define WFC_UPLOAD_PATCH               0xA3
-#define WFC_UPLOAD_PROGRAM             0xA4
-#define WFC_SET_TUNING                 0xA6
-#define WFC_GET_TUNING                 0xA7
-#define WFC_VMIDI_ON                   0xA8
-#define WFC_VMIDI_OFF                  0xA9
-#define WFC_MIDI_STATUS                        0xAA
-#define WFC_GET_CHANNEL_STATUS         0xAB
-#define WFC_DOWNLOAD_SAMPLE_HEADER     0xAC
-#define WFC_UPLOAD_SAMPLE_HEADER       0xAD
-#define WFC_UPLOAD_MULTISAMPLE         0xAE
-#define WFC_UPLOAD_SAMPLE_ALIAS                0xAF
-#define WFC_IDENTIFY_SAMPLE_TYPE       0xB0
-#define WFC_DOWNLOAD_EDRUM_PROGRAM     0xB1
-#define WFC_UPLOAD_EDRUM_PROGRAM       0xB2
-#define WFC_SET_EDRUM_CHANNEL          0xB3
-#define WFC_INSTOUT_LEVELS             0xB4
-#define WFC_PEAKOUT_LEVELS             0xB5
-#define WFC_REPORT_CHANNEL_PROGRAMS    0xB6
-#define WFC_HARDWARE_VERSION           0xCF
-#define WFC_UPLOAD_SAMPLE_PARAMS       0xD7
-#define WFC_DOWNLOAD_OS                        0xF1
-#define WFC_NOOP                        0xFF
-
-#define WF_MAX_SAMPLE   512
-#define WF_MAX_PATCH    256
-#define WF_MAX_PROGRAM  128
-
-#define WF_SECTION_MAX  44   /* longest OS section length */
-
-/* # of bytes we send to the board when sending it various kinds of
-   substantive data, such as samples, patches and programs.
-*/
-
-#define WF_PROGRAM_BYTES 32
-#define WF_PATCH_BYTES 132
-#define WF_SAMPLE_BYTES 27
-#define WF_SAMPLE_HDR_BYTES 25
-#define WF_ALIAS_BYTES 25
-#define WF_DRUM_BYTES 9
-#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
-
-#define WF_ACK     0x80
-#define WF_DMA_ACK 0x81
-
-/* OR-values for MIDI status bits */
-
-#define WF_MIDI_VIRTUAL_ENABLED 0x1
-#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
-#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
-
-/* slot indexes for struct address_info: makes code a little more mnemonic */
-
-#define WF_SYNTH_SLOT         0
-#define WF_INTERNAL_MIDI_SLOT 1
-#define WF_EXTERNAL_MIDI_SLOT 2
-
-/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
-   emulation. Note these NEVER show up in output from the device and
-   should NEVER be used in input unless Virtual MIDI mode has been 
-   disabled. If they do show up as input, the results are unpredictable.
-*/
-
-#define WF_EXTERNAL_SWITCH  0xFD
-#define WF_INTERNAL_SWITCH  0xF9
-
-/* Debugging flags */
-
-#define WF_DEBUG_CMD 0x1
-#define WF_DEBUG_DATA 0x2
-#define WF_DEBUG_LOAD_PATCH 0x4
-#define WF_DEBUG_IO 0x8
-
-/* WavePatch file format stuff */
-
-#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
-#define WF_MAX_COMMENT           64    /*  Comment length */
-#define WF_NUM_LAYERS            4
-#define WF_NAME_LENGTH           32
-#define WF_SOURCE_LENGTH         260
-
-#define BankFileID     "Bank"
-#define DrumkitFileID  "DrumKit"
-#define ProgramFileID  "Program"
-
-struct wf_envelope
-{
-    UCHAR8 attack_time:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 decay1_time:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 decay2_time:7;
-    UCHAR8 Unused3:1;
-
-    UCHAR8 sustain_time:7;
-    UCHAR8 Unused4:1;
-
-    UCHAR8 release_time:7;
-    UCHAR8 Unused5:1;
-
-    UCHAR8 release2_time:7;
-    UCHAR8 Unused6:1;
-
-    CHAR8 attack_level;
-    CHAR8 decay1_level;
-    CHAR8 decay2_level;
-    CHAR8 sustain_level;
-    CHAR8 release_level;
-
-    UCHAR8 attack_velocity:7;
-    UCHAR8 Unused7:1;
-
-    UCHAR8 volume_velocity:7;
-    UCHAR8 Unused8:1;
-
-    UCHAR8 keyboard_scaling:7;
-    UCHAR8 Unused9:1;
-};
-typedef struct wf_envelope wavefront_envelope;
-
-struct wf_lfo
-{
-    UCHAR8 sample_number;
-
-    UCHAR8 frequency:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 am_src:4;
-    UCHAR8 fm_src:4;
-
-    CHAR8 fm_amount;
-    CHAR8 am_amount;
-    CHAR8 start_level;
-    CHAR8 end_level;
-
-    UCHAR8 ramp_delay:7;
-    UCHAR8 wave_restart:1; /* for LFO2 only */
-
-    UCHAR8 ramp_time:7;
-    UCHAR8 Unused2:1;
-};
-typedef struct wf_lfo wavefront_lfo;
-
-struct wf_patch
-{
-    INT16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
-
-    UCHAR8 amplitude_bias:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 portamento:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 sample_number;
-
-    UCHAR8 pitch_bend:4;
-    UCHAR8 sample_msb:1;
-    UCHAR8 Unused3:3;
-
-    UCHAR8 mono:1;
-    UCHAR8 retrigger:1;
-    UCHAR8 nohold:1;
-    UCHAR8 restart:1;
-    UCHAR8 filterconfig:2; /* SDK says "not used" */
-    UCHAR8 reuse:1;
-    UCHAR8 reset_lfo:1;    
-
-    UCHAR8 fm_src2:4;
-    UCHAR8 fm_src1:4;   
-
-    CHAR8 fm_amount1;
-    CHAR8 fm_amount2;
-
-    UCHAR8 am_src:4;
-    UCHAR8 Unused4:4;
-
-    CHAR8 am_amount;
-
-    UCHAR8 fc1_mode:4;
-    UCHAR8 fc2_mode:4;
-
-    CHAR8 fc1_mod_amount;
-    CHAR8 fc1_keyboard_scaling;
-    CHAR8 fc1_bias;
-    CHAR8 fc2_mod_amount;
-    CHAR8 fc2_keyboard_scaling;
-    CHAR8 fc2_bias;
-
-    UCHAR8 randomizer:7;
-    UCHAR8 Unused5:1;
-
-    struct wf_envelope envelope1;
-    struct wf_envelope envelope2;
-    struct wf_lfo lfo1;
-    struct wf_lfo lfo2;
-};
-typedef struct wf_patch wavefront_patch;
-
-struct wf_layer
-{
-    UCHAR8 patch_number;
-
-    UCHAR8 mix_level:7;
-    UCHAR8 mute:1;
-
-    UCHAR8 split_point:7;
-    UCHAR8 play_below:1;
-
-    UCHAR8 pan_mod_src:2;
-    UCHAR8 pan_or_mod:1;
-    UCHAR8 pan:4;
-    UCHAR8 split_type:1;
-};
-typedef struct wf_layer wavefront_layer;
-
-struct wf_program
-{
-    struct wf_layer layer[WF_NUM_LAYERS];
-};
-typedef struct wf_program wavefront_program;
-
-struct wf_sample_offset
-{
-    INT32 Fraction:4;
-    INT32 Integer:20;
-    INT32 Unused:8;
-};
-typedef struct wf_sample_offset wavefront_sample_offset;          
-     
-/* Sample slot types */
-
-#define WF_ST_SAMPLE      0
-#define WF_ST_MULTISAMPLE 1
-#define WF_ST_ALIAS       2
-#define WF_ST_EMPTY       3
-
-/* pseudo's */
-
-#define WF_ST_DRUM        4
-#define WF_ST_PROGRAM     5
-#define WF_ST_PATCH       6
-#define WF_ST_SAMPLEHDR   7
-
-#define WF_ST_MASK        0xf
-
-/* Flags for slot status. These occupy the upper bits of the same byte
-   as a sample type.
-*/
-
-#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
-#define WF_SLOT_FILLED    0x40
-#define WF_SLOT_ROM       0x20
-
-#define WF_SLOT_MASK      0xf0
-
-/* channel constants */
-
-#define WF_CH_MONO  0
-#define WF_CH_LEFT  1
-#define WF_CH_RIGHT 2
-
-/* Sample formats */
-
-#define LINEAR_16BIT 0
-#define WHITE_NOISE  1
-#define LINEAR_8BIT  2
-#define MULAW_8BIT   3
-
-#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
-
-
-/* 
-
-  Because most/all of the sample data we pass in via pointers has
-  never been copied (just mmap-ed into user space straight from the
-  disk), it would be nice to allow handling of multi-channel sample
-  data without forcing user-level extraction of the relevant bytes.
-  
-  So, we need a way of specifying which channel to use (the WaveFront
-  only handles mono samples in a given slot), and the only way to do
-  this without using some struct other than wavefront_sample as the
-  interface is the awful hack of using the unused bits in a
-  wavefront_sample:
-  
-  Val      Meaning
-  ---      -------
-  0        no channel selection (use channel 1, sample is MONO)
-  1        use first channel, and skip one
-  2        use second channel, and skip one
-  3        use third channel, and skip two
-  4        use fourth channel, skip three
-  5        use fifth channel, skip four
-  6        use six channel, skip five
-
-
-  This can handle up to 4 channels, and anyone downloading >4 channels
-  of sample data just to select one of them needs to find some tools
-  like sox ...
-
-  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is 
-  important.
-
-*/
-
-#define WF_SET_CHANNEL(samp,chn) \
- (samp)->Unused1 = chn & 0x1; \
- (samp)->Unused2 = chn & 0x2; \
- (samp)->Unused3 = chn & 0x4 
-  
-#define WF_GET_CHANNEL(samp) \
-  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
-  
-typedef struct wf_sample {
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset loopEndOffset;
-    struct wf_sample_offset sampleEndOffset;
-    INT16 FrequencyBias;
-    UCHAR8 SampleResolution:2;  /* sample_format */
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-} wavefront_sample;
-
-typedef struct wf_multisample {
-    INT16 NumberOfSamples;   /* log2 of the number of samples */
-    INT16 SampleNumber[NUM_MIDIKEYS];
-} wavefront_multisample;
-
-typedef struct wf_alias {
-    INT16 OriginalSample;
-
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset sampleEndOffset;
-    struct wf_sample_offset loopEndOffset;
-
-    INT16  FrequencyBias;
-
-    UCHAR8 SampleResolution:2;
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-    
-    /* This structure is meant to be padded only to 16 bits on their
-       original. Of course, whoever wrote their documentation didn't
-       realize that sizeof(struct) can be >=
-       sum(sizeof(struct-fields)) and so thought that giving a C level
-       description of the structs used in WavePatch files was
-       sufficient. I suppose it was, as long as you remember the 
-       standard 16->32 bit issues.
-    */
-
-    UCHAR8 sixteen_bit_padding;
-} __attribute__((packed)) wavefront_alias;
-
-typedef struct wf_drum {
-    UCHAR8 PatchNumber;
-    UCHAR8 MixLevel:7;
-    UCHAR8 Unmute:1;
-    UCHAR8 Group:4;
-    UCHAR8 Unused1:4;
-    UCHAR8 PanModSource:2;
-    UCHAR8 PanModulated:1;
-    UCHAR8 PanAmount:4;
-    UCHAR8 Unused2:1;
-} wavefront_drum;
-
-typedef struct wf_drumkit {
-    struct wf_drum drum[NUM_MIDIKEYS];
-} wavefront_drumkit;
-
-typedef struct wf_channel_programs {
-    UCHAR8 Program[NUM_MIDICHANNELS];
-} wavefront_channel_programs;
-
-/* How to get MIDI channel status from the data returned by
-   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
-*/
-
-#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
-
-typedef union wf_any {
-    wavefront_sample s;
-    wavefront_multisample ms;
-    wavefront_alias a;
-    wavefront_program pr;
-    wavefront_patch p;
-    wavefront_drum d;
-} wavefront_any;
-
-/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
-   might work for other wave-table based patch loading situations.
-   Alas, his fears were correct. The WaveFront doesn't even come with
-   just "patches", but several different kind of structures that
-   control the sound generation process.
- */
-
-typedef struct wf_patch_info {
-    
-    /* the first two fields are used by the OSS "patch loading" interface
-       only, and are unused by the current user-level library.
-    */
-
-    INT16   key;               /* Use WAVEFRONT_PATCH here */
-    UINT16  devno;             /* fill in when sending */
-    UCHAR8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
-
-#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
-
-    UINT16  number;            /* patch/sample/prog number */
-
-    UINT32  size;              /* size of any data included in 
-                                 one of the fields in `hdrptr', or
-                                 as `dataptr'.
-
-                                 NOTE: for actual samples, this is
-                                 the size of the *SELECTED CHANNEL*
-                                 even if more data is actually available.
-                                 
-                                 So, a stereo sample (2 channels) of
-                                 6000 bytes total has `size' = 3000.
-
-                                 See the macros and comments for
-                                 WF_{GET,SET}_CHANNEL above.
-
-                              */
-    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
-    UINT16 __user *dataptr;            /* actual sample data */
-
-    wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
-} wavefront_patch_info;
-
-/* The maximum number of bytes we will ever move to or from user space
-   in response to a WFC_* command.  This obviously doesn't cover
-   actual sample data.
-*/
-
-#define WF_MAX_READ sizeof(wavefront_multisample)
-#define WF_MAX_WRITE sizeof(wavefront_multisample)
-
-/*
-   This allows us to execute any WF command except the download/upload
-   ones, which are handled differently due to copyin/copyout issues as
-   well as data-nybbling to/from the card.
- */
-
-typedef struct wavefront_control {
-    int cmd;                           /* WFC_* */
-    char status;                       /* return status to user-space */
-    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
-    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
-} wavefront_control;
-
-#define WFCTL_WFCMD    0x1
-#define WFCTL_LOAD_SPP 0x2
-
-/* Modulator table */
-
-#define WF_MOD_LFO1      0
-#define WF_MOD_LFO2      1
-#define WF_MOD_ENV1      2
-#define WF_MOD_ENV2      3
-#define WF_MOD_KEYBOARD  4
-#define WF_MOD_LOGKEY    5
-#define WF_MOD_VELOCITY  6
-#define WF_MOD_LOGVEL    7
-#define WF_MOD_RANDOM    8
-#define WF_MOD_PRESSURE  9
-#define WF_MOD_MOD_WHEEL 10
-#define WF_MOD_1         WF_MOD_MOD_WHEEL 
-#define WF_MOD_BREATH    11
-#define WF_MOD_2         WF_MOD_BREATH
-#define WF_MOD_FOOT      12
-#define WF_MOD_4         WF_MOD_FOOT
-#define WF_MOD_VOLUME    13
-#define WF_MOD_7         WF_MOD_VOLUME
-#define WF_MOD_PAN       14
-#define WF_MOD_10        WF_MOD_PAN
-#define WF_MOD_EXPR      15
-#define WF_MOD_11        WF_MOD_EXPR
-
-/* FX-related material */
-
-typedef struct wf_fx_info {
-    int request;             /* see list below */
-    int data[4];             /* we don't need much */
-} wavefront_fx_info;
-
-/* support for each of these will be forthcoming once I or someone 
-   else has figured out which of the addresses on page 6 and page 7 of 
-   the YSS225 control each parameter. Incidentally, these come from
-   the Windows driver interface, but again, Turtle Beach didn't
-   document the API to use them.
-*/
-
-#define WFFX_SETOUTGAIN                        0
-#define WFFX_SETSTEREOOUTGAIN          1
-#define WFFX_SETREVERBIN1GAIN          2
-#define WFFX_SETREVERBIN2GAIN          3
-#define WFFX_SETREVERBIN3GAIN          4
-#define WFFX_SETCHORUSINPORT           5
-#define WFFX_SETREVERBIN1PORT          6
-#define WFFX_SETREVERBIN2PORT          7
-#define WFFX_SETREVERBIN3PORT          8
-#define WFFX_SETEFFECTPORT             9
-#define WFFX_SETAUXPORT                        10
-#define WFFX_SETREVERBTYPE             11
-#define WFFX_SETREVERBDELAY            12
-#define WFFX_SETCHORUSLFO              13
-#define WFFX_SETCHORUSPMD              14
-#define WFFX_SETCHORUSAMD              15
-#define WFFX_SETEFFECT                 16
-#define WFFX_SETBASEALL                        17
-#define WFFX_SETREVERBALL              18
-#define WFFX_SETCHORUSALL              20
-#define WFFX_SETREVERBDEF              22
-#define WFFX_SETCHORUSDEF              23
-#define WFFX_DELAYSETINGAIN            24
-#define WFFX_DELAYSETFBGAIN            25
-#define WFFX_DELAYSETFBLPF             26
-#define WFFX_DELAYSETGAIN              27
-#define WFFX_DELAYSETTIME              28
-#define WFFX_DELAYSETFBTIME            29
-#define WFFX_DELAYSETALL               30
-#define WFFX_DELAYSETDEF               32
-#define WFFX_SDELAYSETINGAIN           33
-#define WFFX_SDELAYSETFBGAIN           34
-#define WFFX_SDELAYSETFBLPF            35
-#define WFFX_SDELAYSETGAIN             36
-#define WFFX_SDELAYSETTIME             37
-#define WFFX_SDELAYSETFBTIME           38
-#define WFFX_SDELAYSETALL              39
-#define WFFX_SDELAYSETDEF              41
-#define WFFX_DEQSETINGAIN              42
-#define WFFX_DEQSETFILTER              43
-#define WFFX_DEQSETALL                 44
-#define WFFX_DEQSETDEF                 46
-#define WFFX_MUTE                      47
-#define WFFX_FLANGESETBALANCE          48      
-#define WFFX_FLANGESETDELAY            49
-#define WFFX_FLANGESETDWFFX_TH         50
-#define WFFX_FLANGESETFBGAIN           51
-#define WFFX_FLANGESETINGAIN           52
-#define WFFX_FLANGESETLFO              53
-#define WFFX_FLANGESETALL              54
-#define WFFX_FLANGESETDEF              56
-#define WFFX_PITCHSETSHIFT             57
-#define WFFX_PITCHSETBALANCE           58
-#define WFFX_PITCHSETALL               59
-#define WFFX_PITCHSETDEF               61
-#define WFFX_SRSSETINGAIN              62
-#define WFFX_SRSSETSPACE               63
-#define WFFX_SRSSETCENTER              64
-#define WFFX_SRSSETGAIN                        65
-#define WFFX_SRSSETMODE                        66
-#define WFFX_SRSSETDEF                 68
-
-/* Allow direct user-space control over FX memory/coefficient data.
-   In theory this could be used to download the FX microprogram,
-   but it would be a little slower, and involve some weird code.
- */
-
-#define WFFX_MEMSET              69
-
-#endif /* __wavefront_h__ */
index 4f4d98addb448afb61cd3d49b4a2a8cc3a00cbea..a341c803286617d570fac7cda0ad11ced9d67536 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * include/linux/writeback.h.
+ * include/linux/writeback.h
  */
 #ifndef WRITEBACK_H
 #define WRITEBACK_H
index f06cc88607f51dd63bb74a8497fee79629d55ffd..c99d261df8f72adbb034fec1970ee5ff2b2c9ded 100644 (file)
@@ -1,4 +1,4 @@
-/* drivers/video/s1d3xxxfb.h
+/* include/video/s1d13xxxfb.h
  *
  * (c) 2004 Simtec Electronics
  * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
index c45ae86cec31efba043d21d531c6e64f4bce5fc5..7c274002c9f5911d21a5f6a704e85be40d1e1777 100644 (file)
@@ -2,7 +2,7 @@
  * POSIX message queues filesystem for Linux.
  *
  * Copyright (C) 2003,2004  Krzysztof Benedyczak    (golbi@mat.uni.torun.pl)
- *                          Michal Wronski          (Michal.Wronski@motorola.com)
+ *                          Michal Wronski          (michal.wronski@gmail.com)
  *
  * Spinlocks:               Mohamed Abbas           (abbas.mohamed@intel.com)
  * Lockless receive & send, fd based notify:
index 66cfb87646eb2cd2d207fd69ad895674931749d4..0992616eeed6fee540337d595800667db4bf838d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/ipc/util.c
+ * linux/ipc/msgutil.c
  * Copyright (C) 1999, 2004 Manfred Spraul
  *
  * This file is released under GNU General Public Licence version 2 or
index d948ca12acf0e5b3ad113ec77680067f42923ada..5e3f3b75563aa2583771330da7f3b7d84848bc20 100644 (file)
@@ -8,7 +8,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
            signal.o sys.o kmod.o workqueue.o pid.o \
            rcupdate.o extable.o params.o posix-timers.o \
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
-           hrtimer.o rwsem.o latency.o nsproxy.o
+           hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
index 1a58a81fb09dd7a5e838267a61d17453ca99aa8c..4f40d923af8ea2a349736c793d2164c72aa4fa63 100644 (file)
@@ -411,7 +411,6 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
                case AUDIT_FSGID:
                case AUDIT_LOGINUID:
                case AUDIT_PERS:
-               case AUDIT_ARCH:
                case AUDIT_MSGTYPE:
                case AUDIT_PPID:
                case AUDIT_DEVMAJOR:
@@ -423,6 +422,14 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
                case AUDIT_ARG2:
                case AUDIT_ARG3:
                        break;
+               /* arch is only allowed to be = or != */
+               case AUDIT_ARCH:
+                       if ((f->op != AUDIT_NOT_EQUAL) && (f->op != AUDIT_EQUAL)
+                                       && (f->op != AUDIT_NEGATE) && (f->op)) {
+                               err = -EINVAL;
+                               goto exit_free;
+                       }
+                       break;
                case AUDIT_PERM:
                        if (f->val & ~15)
                                goto exit_free;
index 105147631753f1b4f68fc17878a0e4531b436593..42f2f11797111de0af926f82fead3a5e86ce2ee5 100644 (file)
@@ -278,8 +278,11 @@ static int audit_filter_rules(struct task_struct *tsk,
                        result = audit_comparator(tsk->pid, f->op, f->val);
                        break;
                case AUDIT_PPID:
-                       if (ctx)
+                       if (ctx) {
+                               if (!ctx->ppid)
+                                       ctx->ppid = sys_getppid();
                                result = audit_comparator(ctx->ppid, f->op, f->val);
+                       }
                        break;
                case AUDIT_UID:
                        result = audit_comparator(tsk->uid, f->op, f->val);
@@ -795,7 +798,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
 
        /* tsk == current */
        context->pid = tsk->pid;
-       context->ppid = sys_getppid();  /* sic.  tsk == current in all cases */
+       if (!context->ppid)
+               context->ppid = sys_getppid();
        context->uid = tsk->uid;
        context->gid = tsk->gid;
        context->euid = tsk->euid;
@@ -1137,6 +1141,7 @@ void audit_syscall_entry(int arch, int major,
        context->ctime      = CURRENT_TIME;
        context->in_syscall = 1;
        context->auditable  = !!(state == AUDIT_RECORD_CONTEXT);
+       context->ppid       = 0;
 }
 
 /**
@@ -1352,7 +1357,13 @@ void __audit_inode_child(const char *dname, const struct inode *inode,
                }
 
 update_context:
-       idx = context->name_count++;
+       idx = context->name_count;
+       if (context->name_count == AUDIT_NAMES) {
+               printk(KERN_DEBUG "name_count maxed and losing %s\n",
+                       found_name ?: "(null)");
+               return;
+       }
+       context->name_count++;
 #if AUDIT_DEBUG
        context->ino_count++;
 #endif
@@ -1370,7 +1381,16 @@ update_context:
        /* A parent was not found in audit_names, so copy the inode data for the
         * provided parent. */
        if (!found_name) {
-               idx = context->name_count++;
+               idx = context->name_count;
+               if (context->name_count == AUDIT_NAMES) {
+                       printk(KERN_DEBUG
+                               "name_count maxed and losing parent inode data: dev=%02x:%02x, inode=%lu",
+                               MAJOR(parent->i_sb->s_dev),
+                               MINOR(parent->i_sb->s_dev),
+                               parent->i_ino);
+                       return;
+               }
+               context->name_count++;
 #if AUDIT_DEBUG
                context->ino_count++;
 #endif
index 736cb0bd498f8ff5c7a50d8b60e3130da43d9d7f..4cf65f5c6a74f5697d7411391207cdcd5431e1ea 100644 (file)
 
 #include "internals.h"
 
+/**
+ *     dynamic_irq_init - initialize a dynamically allocated irq
+ *     @irq:   irq number to initialize
+ */
+void dynamic_irq_init(unsigned int irq)
+{
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       if (irq >= NR_IRQS) {
+               printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
+               WARN_ON(1);
+               return;
+       }
+
+       /* Ensure we don't have left over values from a previous use of this irq */
+       desc = irq_desc + irq;
+       spin_lock_irqsave(&desc->lock, flags);
+       desc->status = IRQ_DISABLED;
+       desc->chip = &no_irq_chip;
+       desc->handle_irq = handle_bad_irq;
+       desc->depth = 1;
+       desc->handler_data = NULL;
+       desc->chip_data = NULL;
+       desc->action = NULL;
+       desc->irq_count = 0;
+       desc->irqs_unhandled = 0;
+#ifdef CONFIG_SMP
+       desc->affinity = CPU_MASK_ALL;
+#endif
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *     dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ *     @irq:   irq number to initialize
+ */
+void dynamic_irq_cleanup(unsigned int irq)
+{
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       if (irq >= NR_IRQS) {
+               printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
+               WARN_ON(1);
+               return;
+       }
+
+       desc = irq_desc + irq;
+       spin_lock_irqsave(&desc->lock, flags);
+       if (desc->action) {
+               spin_unlock_irqrestore(&desc->lock, flags);
+               printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n",
+                       irq);
+               WARN_ON(1);
+               return;
+       }
+       desc->handle_irq = handle_bad_irq;
+       desc->chip = &no_irq_chip;
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+
 /**
  *     set_irq_chip - set the irq chip for an irq
  *     @irq:   irq number
index a57ebe9fa6f6b89169eb7e7e093167c341caed71..4baa3bbcd25a0c516e7ae05de2eeed2dbd523814 100644 (file)
@@ -7,17 +7,17 @@ void set_pending_irq(unsigned int irq, cpumask_t mask)
        unsigned long flags;
 
        spin_lock_irqsave(&desc->lock, flags);
-       desc->move_irq = 1;
+       desc->status |= IRQ_MOVE_PENDING;
        irq_desc[irq].pending_mask = mask;
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-void move_native_irq(int irq)
+void move_masked_irq(int irq)
 {
        struct irq_desc *desc = irq_desc + irq;
        cpumask_t tmp;
 
-       if (likely(!desc->move_irq))
+       if (likely(!(desc->status & IRQ_MOVE_PENDING)))
                return;
 
        /*
@@ -28,7 +28,7 @@ void move_native_irq(int irq)
                return;
        }
 
-       desc->move_irq = 0;
+       desc->status &= ~IRQ_MOVE_PENDING;
 
        if (unlikely(cpus_empty(irq_desc[irq].pending_mask)))
                return;
@@ -48,15 +48,29 @@ void move_native_irq(int irq)
         * when an active trigger is comming in. This could
         * cause some ioapics to mal-function.
         * Being paranoid i guess!
+        *
+        * For correct operation this depends on the caller
+        * masking the irqs.
         */
        if (likely(!cpus_empty(tmp))) {
-               if (likely(!(desc->status & IRQ_DISABLED)))
-                       desc->chip->disable(irq);
-
                desc->chip->set_affinity(irq,tmp);
-
-               if (likely(!(desc->status & IRQ_DISABLED)))
-                       desc->chip->enable(irq);
        }
        cpus_clear(irq_desc[irq].pending_mask);
 }
+
+void move_native_irq(int irq)
+{
+       struct irq_desc *desc = irq_desc + irq;
+
+       if (likely(!(desc->status & IRQ_MOVE_PENDING)))
+               return;
+
+       if (likely(!(desc->status & IRQ_DISABLED)))
+               desc->chip->disable(irq);
+
+       move_masked_irq(irq);
+
+       if (likely(!(desc->status & IRQ_DISABLED)))
+               desc->chip->enable(irq);
+}
+
index e5ebcc1ec3a0f4c612ca4f9db9ead45d07d424ce..9cbb5d1be06f7420005bdf32538777deb844af03 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/kernel/posix_timers.c
+ * linux/kernel/posix-timers.c
  *
  *
  * 2002-10-15  Posix Clocks & timers
index 523e46483b99e6b3bbee6376c7a4232dc71adca4..26bb5ffe1ef14ef61824180dd6163acdc104006d 100644 (file)
@@ -71,9 +71,6 @@ static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
 static int blimit = 10;
 static int qhimark = 10000;
 static int qlowmark = 100;
-#ifdef CONFIG_SMP
-static int rsinterval = 1000;
-#endif
 
 static atomic_t rcu_barrier_cpu_count;
 static DEFINE_MUTEX(rcu_barrier_mutex);
@@ -86,8 +83,8 @@ static void force_quiescent_state(struct rcu_data *rdp,
        int cpu;
        cpumask_t cpumask;
        set_need_resched();
-       if (unlikely(rdp->qlen - rdp->last_rs_qlen > rsinterval)) {
-               rdp->last_rs_qlen = rdp->qlen;
+       if (unlikely(!rcp->signaled)) {
+               rcp->signaled = 1;
                /*
                 * Don't send IPI to itself. With irqs disabled,
                 * rdp->cpu is the current cpu.
@@ -301,6 +298,7 @@ static void rcu_start_batch(struct rcu_ctrlblk *rcp)
                smp_mb();
                cpus_andnot(rcp->cpumask, cpu_online_map, nohz_cpu_mask);
 
+               rcp->signaled = 0;
        }
 }
 
@@ -628,9 +626,6 @@ void synchronize_rcu(void)
 module_param(blimit, int, 0);
 module_param(qhimark, int, 0);
 module_param(qlowmark, int, 0);
-#ifdef CONFIG_SMP
-module_param(rsinterval, int, 0);
-#endif
 EXPORT_SYMBOL_GPL(rcu_batches_completed);
 EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
 EXPORT_SYMBOL_GPL(call_rcu);
index 4f2c4272d59c91bda58823e8f6e04e121c85458d..e2bda18f6f42779144829a2150b4e6fb8ac4b338 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) IBM Corporation, 2005
+ * Copyright (C) IBM Corporation, 2005, 2006
  *
  * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *          Josh Triplett <josh@freedesktop.org>
  *
  * See also:  Documentation/RCU/torture.txt
  */
 #include <linux/delay.h>
 #include <linux/byteorder/swabb.h>
 #include <linux/stat.h>
+#include <linux/srcu.h>
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
+              "Josh Triplett <josh@freedesktop.org>");
 
-static int nreaders = -1;      /* # reader threads, defaults to 4*ncpus */
+static int nreaders = -1;      /* # reader threads, defaults to 2*ncpus */
+static int nfakewriters = 4;   /* # fake writer threads */
 static int stat_interval;      /* Interval between stats, in seconds. */
                                /*  Defaults to "only at end of test". */
 static int verbose;            /* Print more debug info. */
 static int test_no_idle_hz;    /* Test RCU's support for tickless idle CPUs. */
 static int shuffle_interval = 5; /* Interval between shuffles (in sec)*/
-static char *torture_type = "rcu"; /* What to torture. */
+static char *torture_type = "rcu"; /* What RCU implementation to torture. */
 
 module_param(nreaders, int, 0);
 MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+module_param(nfakewriters, int, 0);
+MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads");
 module_param(stat_interval, int, 0);
 MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
 module_param(verbose, bool, 0);
@@ -66,7 +73,7 @@ MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs");
 module_param(shuffle_interval, int, 0);
 MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
 module_param(torture_type, charp, 0);
-MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh)");
+MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, srcu)");
 
 #define TORTURE_FLAG "-torture:"
 #define PRINTK_STRING(s) \
@@ -80,6 +87,7 @@ static char printk_buf[4096];
 
 static int nrealreaders;
 static struct task_struct *writer_task;
+static struct task_struct **fakewriter_tasks;
 static struct task_struct **reader_tasks;
 static struct task_struct *stats_task;
 static struct task_struct *shuffler_task;
@@ -104,11 +112,12 @@ static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
 static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
        { 0 };
 static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
-atomic_t n_rcu_torture_alloc;
-atomic_t n_rcu_torture_alloc_fail;
-atomic_t n_rcu_torture_free;
-atomic_t n_rcu_torture_mberror;
-atomic_t n_rcu_torture_error;
+static atomic_t n_rcu_torture_alloc;
+static atomic_t n_rcu_torture_alloc_fail;
+static atomic_t n_rcu_torture_free;
+static atomic_t n_rcu_torture_mberror;
+static atomic_t n_rcu_torture_error;
+static struct list_head rcu_torture_removed;
 
 /*
  * Allocate an element from the rcu_tortures pool.
@@ -145,7 +154,7 @@ rcu_torture_free(struct rcu_torture *p)
 
 struct rcu_random_state {
        unsigned long rrs_state;
-       unsigned long rrs_count;
+       long rrs_count;
 };
 
 #define RCU_RANDOM_MULT 39916801  /* prime */
@@ -158,7 +167,7 @@ struct rcu_random_state {
  * Crude but fast random-number generator.  Uses a linear congruential
  * generator, with occasional help from get_random_bytes().
  */
-static long
+static unsigned long
 rcu_random(struct rcu_random_state *rrsp)
 {
        long refresh;
@@ -180,9 +189,11 @@ struct rcu_torture_ops {
        void (*init)(void);
        void (*cleanup)(void);
        int (*readlock)(void);
+       void (*readdelay)(struct rcu_random_state *rrsp);
        void (*readunlock)(int idx);
        int (*completed)(void);
        void (*deferredfree)(struct rcu_torture *p);
+       void (*sync)(void);
        int (*stats)(char *page);
        char *name;
 };
@@ -198,6 +209,18 @@ static int rcu_torture_read_lock(void) __acquires(RCU)
        return 0;
 }
 
+static void rcu_read_delay(struct rcu_random_state *rrsp)
+{
+       long delay;
+       const long longdelay = 200;
+
+       /* We want there to be long-running readers, but not all the time. */
+
+       delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay);
+       if (!delay)
+               udelay(longdelay);
+}
+
 static void rcu_torture_read_unlock(int idx) __releases(RCU)
 {
        rcu_read_unlock();
@@ -239,13 +262,54 @@ static struct rcu_torture_ops rcu_ops = {
        .init = NULL,
        .cleanup = NULL,
        .readlock = rcu_torture_read_lock,
+       .readdelay = rcu_read_delay,
        .readunlock = rcu_torture_read_unlock,
        .completed = rcu_torture_completed,
        .deferredfree = rcu_torture_deferred_free,
+       .sync = synchronize_rcu,
        .stats = NULL,
        .name = "rcu"
 };
 
+static void rcu_sync_torture_deferred_free(struct rcu_torture *p)
+{
+       int i;
+       struct rcu_torture *rp;
+       struct rcu_torture *rp1;
+
+       cur_ops->sync();
+       list_add(&p->rtort_free, &rcu_torture_removed);
+       list_for_each_entry_safe(rp, rp1, &rcu_torture_removed, rtort_free) {
+               i = rp->rtort_pipe_count;
+               if (i > RCU_TORTURE_PIPE_LEN)
+                       i = RCU_TORTURE_PIPE_LEN;
+               atomic_inc(&rcu_torture_wcount[i]);
+               if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
+                       rp->rtort_mbtest = 0;
+                       list_del(&rp->rtort_free);
+                       rcu_torture_free(rp);
+               }
+       }
+}
+
+static void rcu_sync_torture_init(void)
+{
+       INIT_LIST_HEAD(&rcu_torture_removed);
+}
+
+static struct rcu_torture_ops rcu_sync_ops = {
+       .init = rcu_sync_torture_init,
+       .cleanup = NULL,
+       .readlock = rcu_torture_read_lock,
+       .readdelay = rcu_read_delay,
+       .readunlock = rcu_torture_read_unlock,
+       .completed = rcu_torture_completed,
+       .deferredfree = rcu_sync_torture_deferred_free,
+       .sync = synchronize_rcu,
+       .stats = NULL,
+       .name = "rcu_sync"
+};
+
 /*
  * Definitions for rcu_bh torture testing.
  */
@@ -271,19 +335,176 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
        call_rcu_bh(&p->rtort_rcu, rcu_torture_cb);
 }
 
+struct rcu_bh_torture_synchronize {
+       struct rcu_head head;
+       struct completion completion;
+};
+
+static void rcu_bh_torture_wakeme_after_cb(struct rcu_head *head)
+{
+       struct rcu_bh_torture_synchronize *rcu;
+
+       rcu = container_of(head, struct rcu_bh_torture_synchronize, head);
+       complete(&rcu->completion);
+}
+
+static void rcu_bh_torture_synchronize(void)
+{
+       struct rcu_bh_torture_synchronize rcu;
+
+       init_completion(&rcu.completion);
+       call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
+       wait_for_completion(&rcu.completion);
+}
+
 static struct rcu_torture_ops rcu_bh_ops = {
        .init = NULL,
        .cleanup = NULL,
        .readlock = rcu_bh_torture_read_lock,
+       .readdelay = rcu_read_delay,  /* just reuse rcu's version. */
        .readunlock = rcu_bh_torture_read_unlock,
        .completed = rcu_bh_torture_completed,
        .deferredfree = rcu_bh_torture_deferred_free,
+       .sync = rcu_bh_torture_synchronize,
        .stats = NULL,
        .name = "rcu_bh"
 };
 
+static struct rcu_torture_ops rcu_bh_sync_ops = {
+       .init = rcu_sync_torture_init,
+       .cleanup = NULL,
+       .readlock = rcu_bh_torture_read_lock,
+       .readdelay = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock = rcu_bh_torture_read_unlock,
+       .completed = rcu_bh_torture_completed,
+       .deferredfree = rcu_sync_torture_deferred_free,
+       .sync = rcu_bh_torture_synchronize,
+       .stats = NULL,
+       .name = "rcu_bh_sync"
+};
+
+/*
+ * Definitions for srcu torture testing.
+ */
+
+static struct srcu_struct srcu_ctl;
+
+static void srcu_torture_init(void)
+{
+       init_srcu_struct(&srcu_ctl);
+       rcu_sync_torture_init();
+}
+
+static void srcu_torture_cleanup(void)
+{
+       synchronize_srcu(&srcu_ctl);
+       cleanup_srcu_struct(&srcu_ctl);
+}
+
+static int srcu_torture_read_lock(void)
+{
+       return srcu_read_lock(&srcu_ctl);
+}
+
+static void srcu_read_delay(struct rcu_random_state *rrsp)
+{
+       long delay;
+       const long uspertick = 1000000 / HZ;
+       const long longdelay = 10;
+
+       /* We want there to be long-running readers, but not all the time. */
+
+       delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick);
+       if (!delay)
+               schedule_timeout_interruptible(longdelay);
+}
+
+static void srcu_torture_read_unlock(int idx)
+{
+       srcu_read_unlock(&srcu_ctl, idx);
+}
+
+static int srcu_torture_completed(void)
+{
+       return srcu_batches_completed(&srcu_ctl);
+}
+
+static void srcu_torture_synchronize(void)
+{
+       synchronize_srcu(&srcu_ctl);
+}
+
+static int srcu_torture_stats(char *page)
+{
+       int cnt = 0;
+       int cpu;
+       int idx = srcu_ctl.completed & 0x1;
+
+       cnt += sprintf(&page[cnt], "%s%s per-CPU(idx=%d):",
+                      torture_type, TORTURE_FLAG, idx);
+       for_each_possible_cpu(cpu) {
+               cnt += sprintf(&page[cnt], " %d(%d,%d)", cpu,
+                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx],
+                              per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]);
+       }
+       cnt += sprintf(&page[cnt], "\n");
+       return cnt;
+}
+
+static struct rcu_torture_ops srcu_ops = {
+       .init = srcu_torture_init,
+       .cleanup = srcu_torture_cleanup,
+       .readlock = srcu_torture_read_lock,
+       .readdelay = srcu_read_delay,
+       .readunlock = srcu_torture_read_unlock,
+       .completed = srcu_torture_completed,
+       .deferredfree = rcu_sync_torture_deferred_free,
+       .sync = srcu_torture_synchronize,
+       .stats = srcu_torture_stats,
+       .name = "srcu"
+};
+
+/*
+ * Definitions for sched torture testing.
+ */
+
+static int sched_torture_read_lock(void)
+{
+       preempt_disable();
+       return 0;
+}
+
+static void sched_torture_read_unlock(int idx)
+{
+       preempt_enable();
+}
+
+static int sched_torture_completed(void)
+{
+       return 0;
+}
+
+static void sched_torture_synchronize(void)
+{
+       synchronize_sched();
+}
+
+static struct rcu_torture_ops sched_ops = {
+       .init = rcu_sync_torture_init,
+       .cleanup = NULL,
+       .readlock = sched_torture_read_lock,
+       .readdelay = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock = sched_torture_read_unlock,
+       .completed = sched_torture_completed,
+       .deferredfree = rcu_sync_torture_deferred_free,
+       .sync = sched_torture_synchronize,
+       .stats = NULL,
+       .name = "sched"
+};
+
 static struct rcu_torture_ops *torture_ops[] =
-       { &rcu_ops, &rcu_bh_ops, NULL };
+       { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &srcu_ops,
+         &sched_ops, NULL };
 
 /*
  * RCU torture writer kthread.  Repeatedly substitutes a new structure
@@ -329,6 +550,30 @@ rcu_torture_writer(void *arg)
        return 0;
 }
 
+/*
+ * RCU torture fake writer kthread.  Repeatedly calls sync, with a random
+ * delay between calls.
+ */
+static int
+rcu_torture_fakewriter(void *arg)
+{
+       DEFINE_RCU_RANDOM(rand);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task started");
+       set_user_nice(current, 19);
+
+       do {
+               schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
+               udelay(rcu_random(&rand) & 0x3ff);
+               cur_ops->sync();
+       } while (!kthread_should_stop() && !fullstop);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
 /*
  * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
  * incrementing the corresponding element of the pipeline array.  The
@@ -359,7 +604,7 @@ rcu_torture_reader(void *arg)
                }
                if (p->rtort_mbtest == 0)
                        atomic_inc(&n_rcu_torture_mberror);
-               udelay(rcu_random(&rand) & 0x7f);
+               cur_ops->readdelay(&rand);
                preempt_disable();
                pipe_count = p->rtort_pipe_count;
                if (pipe_count > RCU_TORTURE_PIPE_LEN) {
@@ -483,7 +728,7 @@ static int rcu_idle_cpu;    /* Force all torture tasks off this CPU */
 /* Shuffle tasks such that we allow @rcu_idle_cpu to become idle. A special case
  * is when @rcu_idle_cpu = -1, when we allow the tasks to run on all CPUs.
  */
-void rcu_torture_shuffle_tasks(void)
+static void rcu_torture_shuffle_tasks(void)
 {
        cpumask_t tmp_mask = CPU_MASK_ALL;
        int i;
@@ -507,6 +752,12 @@ void rcu_torture_shuffle_tasks(void)
                                set_cpus_allowed(reader_tasks[i], tmp_mask);
        }
 
+       if (fakewriter_tasks != NULL) {
+               for (i = 0; i < nfakewriters; i++)
+                       if (fakewriter_tasks[i])
+                               set_cpus_allowed(fakewriter_tasks[i], tmp_mask);
+       }
+
        if (writer_task)
                set_cpus_allowed(writer_task, tmp_mask);
 
@@ -540,11 +791,12 @@ rcu_torture_shuffle(void *arg)
 static inline void
 rcu_torture_print_module_parms(char *tag)
 {
-       printk(KERN_ALERT "%s" TORTURE_FLAG "--- %s: nreaders=%d "
+       printk(KERN_ALERT "%s" TORTURE_FLAG
+               "--- %s: nreaders=%d nfakewriters=%d "
                "stat_interval=%d verbose=%d test_no_idle_hz=%d "
                "shuffle_interval = %d\n",
-               torture_type, tag, nrealreaders, stat_interval, verbose,
-               test_no_idle_hz, shuffle_interval);
+               torture_type, tag, nrealreaders, nfakewriters,
+               stat_interval, verbose, test_no_idle_hz, shuffle_interval);
 }
 
 static void
@@ -579,6 +831,19 @@ rcu_torture_cleanup(void)
        }
        rcu_torture_current = NULL;
 
+       if (fakewriter_tasks != NULL) {
+               for (i = 0; i < nfakewriters; i++) {
+                       if (fakewriter_tasks[i] != NULL) {
+                               VERBOSE_PRINTK_STRING(
+                                       "Stopping rcu_torture_fakewriter task");
+                               kthread_stop(fakewriter_tasks[i]);
+                       }
+                       fakewriter_tasks[i] = NULL;
+               }
+               kfree(fakewriter_tasks);
+               fakewriter_tasks = NULL;
+       }
+
        if (stats_task != NULL) {
                VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
                kthread_stop(stats_task);
@@ -666,7 +931,25 @@ rcu_torture_init(void)
                writer_task = NULL;
                goto unwind;
        }
-       reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
+       fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
+                                  GFP_KERNEL);
+       if (fakewriter_tasks == NULL) {
+               VERBOSE_PRINTK_ERRSTRING("out of memory");
+               firsterr = -ENOMEM;
+               goto unwind;
+       }
+       for (i = 0; i < nfakewriters; i++) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task");
+               fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL,
+                                                 "rcu_torture_fakewriter");
+               if (IS_ERR(fakewriter_tasks[i])) {
+                       firsterr = PTR_ERR(fakewriter_tasks[i]);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter");
+                       fakewriter_tasks[i] = NULL;
+                       goto unwind;
+               }
+       }
+       reader_tasks = kzalloc(nrealreaders * sizeof(reader_tasks[0]),
                               GFP_KERNEL);
        if (reader_tasks == NULL) {
                VERBOSE_PRINTK_ERRSTRING("out of memory");
diff --git a/kernel/srcu.c b/kernel/srcu.c
new file mode 100644 (file)
index 0000000..3507cab
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Sleepable Read-Copy Update mechanism for mutual exclusion.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Author: Paul McKenney <paulmck@us.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU/ *.txt
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/preempt.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/srcu.h>
+
+/**
+ * init_srcu_struct - initialize a sleep-RCU structure
+ * @sp: structure to initialize.
+ *
+ * Must invoke this on a given srcu_struct before passing that srcu_struct
+ * to any other function.  Each srcu_struct represents a separate domain
+ * of SRCU protection.
+ */
+int init_srcu_struct(struct srcu_struct *sp)
+{
+       sp->completed = 0;
+       mutex_init(&sp->mutex);
+       sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
+       return (sp->per_cpu_ref ? 0 : -ENOMEM);
+}
+
+/*
+ * srcu_readers_active_idx -- returns approximate number of readers
+ *     active on the specified rank of per-CPU counters.
+ */
+
+static int srcu_readers_active_idx(struct srcu_struct *sp, int idx)
+{
+       int cpu;
+       int sum;
+
+       sum = 0;
+       for_each_possible_cpu(cpu)
+               sum += per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx];
+       return sum;
+}
+
+/**
+ * srcu_readers_active - returns approximate number of readers.
+ * @sp: which srcu_struct to count active readers (holding srcu_read_lock).
+ *
+ * Note that this is not an atomic primitive, and can therefore suffer
+ * severe errors when invoked on an active srcu_struct.  That said, it
+ * can be useful as an error check at cleanup time.
+ */
+int srcu_readers_active(struct srcu_struct *sp)
+{
+       return srcu_readers_active_idx(sp, 0) + srcu_readers_active_idx(sp, 1);
+}
+
+/**
+ * cleanup_srcu_struct - deconstruct a sleep-RCU structure
+ * @sp: structure to clean up.
+ *
+ * Must invoke this after you are finished using a given srcu_struct that
+ * was initialized via init_srcu_struct(), else you leak memory.
+ */
+void cleanup_srcu_struct(struct srcu_struct *sp)
+{
+       int sum;
+
+       sum = srcu_readers_active(sp);
+       WARN_ON(sum);  /* Leakage unless caller handles error. */
+       if (sum != 0)
+               return;
+       free_percpu(sp->per_cpu_ref);
+       sp->per_cpu_ref = NULL;
+}
+
+/**
+ * srcu_read_lock - register a new reader for an SRCU-protected structure.
+ * @sp: srcu_struct in which to register the new reader.
+ *
+ * Counts the new reader in the appropriate per-CPU element of the
+ * srcu_struct.  Must be called from process context.
+ * Returns an index that must be passed to the matching srcu_read_unlock().
+ */
+int srcu_read_lock(struct srcu_struct *sp)
+{
+       int idx;
+
+       preempt_disable();
+       idx = sp->completed & 0x1;
+       barrier();  /* ensure compiler looks -once- at sp->completed. */
+       per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]++;
+       srcu_barrier();  /* ensure compiler won't misorder critical section. */
+       preempt_enable();
+       return idx;
+}
+
+/**
+ * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
+ * @sp: srcu_struct in which to unregister the old reader.
+ * @idx: return value from corresponding srcu_read_lock().
+ *
+ * Removes the count for the old reader from the appropriate per-CPU
+ * element of the srcu_struct.  Note that this may well be a different
+ * CPU than that which was incremented by the corresponding srcu_read_lock().
+ * Must be called from process context.
+ */
+void srcu_read_unlock(struct srcu_struct *sp, int idx)
+{
+       preempt_disable();
+       srcu_barrier();  /* ensure compiler won't misorder critical section. */
+       per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--;
+       preempt_enable();
+}
+
+/**
+ * synchronize_srcu - wait for prior SRCU read-side critical-section completion
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates.  Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchornize_srcu() from the corresponding
+ * SRCU read-side critical section; doing so will result in deadlock.
+ * However, it is perfectly legal to call synchronize_srcu() on one
+ * srcu_struct from some other srcu_struct's read-side critical section.
+ */
+void synchronize_srcu(struct srcu_struct *sp)
+{
+       int idx;
+
+       idx = sp->completed;
+       mutex_lock(&sp->mutex);
+
+       /*
+        * Check to see if someone else did the work for us while we were
+        * waiting to acquire the lock.  We need -two- advances of
+        * the counter, not just one.  If there was but one, we might have
+        * shown up -after- our helper's first synchronize_sched(), thus
+        * having failed to prevent CPU-reordering races with concurrent
+        * srcu_read_unlock()s on other CPUs (see comment below).  So we
+        * either (1) wait for two or (2) supply the second ourselves.
+        */
+
+       if ((sp->completed - idx) >= 2) {
+               mutex_unlock(&sp->mutex);
+               return;
+       }
+
+       synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+       /*
+        * The preceding synchronize_sched() ensures that any CPU that
+        * sees the new value of sp->completed will also see any preceding
+        * changes to data structures made by this CPU.  This prevents
+        * some other CPU from reordering the accesses in its SRCU
+        * read-side critical section to precede the corresponding
+        * srcu_read_lock() -- ensuring that such references will in
+        * fact be protected.
+        *
+        * So it is now safe to do the flip.
+        */
+
+       idx = sp->completed & 0x1;
+       sp->completed++;
+
+       synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+       /*
+        * At this point, because of the preceding synchronize_sched(),
+        * all srcu_read_lock() calls using the old counters have completed.
+        * Their corresponding critical sections might well be still
+        * executing, but the srcu_read_lock() primitives themselves
+        * will have finished executing.
+        */
+
+       while (srcu_readers_active_idx(sp, idx))
+               schedule_timeout_interruptible(1);
+
+       synchronize_sched();  /* Force memory barrier on all CPUs. */
+
+       /*
+        * The preceding synchronize_sched() forces all srcu_read_unlock()
+        * primitives that were executing concurrently with the preceding
+        * for_each_possible_cpu() loop to have completed by this point.
+        * More importantly, it also forces the corresponding SRCU read-side
+        * critical sections to have also completed, and the corresponding
+        * references to SRCU-protected data items to be dropped.
+        *
+        * Note:
+        *
+        *      Despite what you might think at first glance, the
+        *      preceding synchronize_sched() -must- be within the
+        *      critical section ended by the following mutex_unlock().
+        *      Otherwise, a task taking the early exit can race
+        *      with a srcu_read_unlock(), which might have executed
+        *      just before the preceding srcu_readers_active() check,
+        *      and whose CPU might have reordered the srcu_read_unlock()
+        *      with the preceding critical section.  In this case, there
+        *      is nothing preventing the synchronize_sched() task that is
+        *      taking the early exit from freeing a data structure that
+        *      is still being referenced (out of order) by the task
+        *      doing the srcu_read_unlock().
+        *
+        *      Alternatively, the comparison with "2" on the early exit
+        *      could be changed to "3", but this increases synchronize_srcu()
+        *      latency for bulk loads.  So the current code is preferred.
+        */
+
+       mutex_unlock(&sp->mutex);
+}
+
+/**
+ * srcu_batches_completed - return batches completed.
+ * @sp: srcu_struct on which to report batch completion.
+ *
+ * Report the number of batches, correlated with, but not necessarily
+ * precisely the same as, the number of grace periods that have elapsed.
+ */
+
+long srcu_batches_completed(struct srcu_struct *sp)
+{
+       return sp->completed;
+}
+
+EXPORT_SYMBOL_GPL(init_srcu_struct);
+EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
+EXPORT_SYMBOL_GPL(srcu_read_lock);
+EXPORT_SYMBOL_GPL(srcu_read_unlock);
+EXPORT_SYMBOL_GPL(synchronize_srcu);
+EXPORT_SYMBOL_GPL(srcu_batches_completed);
+EXPORT_SYMBOL_GPL(srcu_readers_active);
index 2314867ae34f138a80daf20e6ed930ef731d8f6e..98489d82801be030cb3477589ed952291e19eb7e 100644 (file)
@@ -153,7 +153,7 @@ static int __kprobes notifier_call_chain(struct notifier_block **nl,
 
 /*
  *     Atomic notifier chain routines.  Registration and unregistration
- *     use a mutex, and call_chain is synchronized by RCU (no locks).
+ *     use a spinlock, and call_chain is synchronized by RCU (no locks).
  */
 
 /**
@@ -401,6 +401,129 @@ int raw_notifier_call_chain(struct raw_notifier_head *nh,
 
 EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
 
+/*
+ *     SRCU notifier chain routines.    Registration and unregistration
+ *     use a mutex, and call_chain is synchronized by SRCU (no locks).
+ */
+
+/**
+ *     srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @n: New entry in notifier chain
+ *
+ *     Adds a notifier to an SRCU notifier chain.
+ *     Must be called in process context.
+ *
+ *     Currently always returns zero.
+ */
+
+int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call mutex_lock().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_register(&nh->head, n);
+
+       mutex_lock(&nh->mutex);
+       ret = notifier_chain_register(&nh->head, n);
+       mutex_unlock(&nh->mutex);
+       return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
+
+/**
+ *     srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @n: Entry to remove from notifier chain
+ *
+ *     Removes a notifier from an SRCU notifier chain.
+ *     Must be called from process context.
+ *
+ *     Returns zero on success or %-ENOENT on failure.
+ */
+int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
+               struct notifier_block *n)
+{
+       int ret;
+
+       /*
+        * This code gets used during boot-up, when task switching is
+        * not yet working and interrupts must remain disabled.  At
+        * such times we must not call mutex_lock().
+        */
+       if (unlikely(system_state == SYSTEM_BOOTING))
+               return notifier_chain_unregister(&nh->head, n);
+
+       mutex_lock(&nh->mutex);
+       ret = notifier_chain_unregister(&nh->head, n);
+       mutex_unlock(&nh->mutex);
+       synchronize_srcu(&nh->srcu);
+       return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
+
+/**
+ *     srcu_notifier_call_chain - Call functions in an SRCU notifier chain
+ *     @nh: Pointer to head of the SRCU notifier chain
+ *     @val: Value passed unmodified to notifier function
+ *     @v: Pointer passed unmodified to notifier function
+ *
+ *     Calls each function in a notifier chain in turn.  The functions
+ *     run in a process context, so they are allowed to block.
+ *
+ *     If the return value of the notifier can be and'ed
+ *     with %NOTIFY_STOP_MASK then srcu_notifier_call_chain
+ *     will return immediately, with the return value of
+ *     the notifier function which halted execution.
+ *     Otherwise the return value is the return value
+ *     of the last notifier function called.
+ */
+
+int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+               unsigned long val, void *v)
+{
+       int ret;
+       int idx;
+
+       idx = srcu_read_lock(&nh->srcu);
+       ret = notifier_call_chain(&nh->head, val, v);
+       srcu_read_unlock(&nh->srcu, idx);
+       return ret;
+}
+
+EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
+
+/**
+ *     srcu_init_notifier_head - Initialize an SRCU notifier head
+ *     @nh: Pointer to head of the srcu notifier chain
+ *
+ *     Unlike other sorts of notifier heads, SRCU notifier heads require
+ *     dynamic initialization.  Be sure to call this routine before
+ *     calling any of the other SRCU notifier routines for this head.
+ *
+ *     If an SRCU notifier head is deallocated, it must first be cleaned
+ *     up by calling srcu_cleanup_notifier_head().  Otherwise the head's
+ *     per-cpu data (used by the SRCU mechanism) will leak.
+ */
+
+void srcu_init_notifier_head(struct srcu_notifier_head *nh)
+{
+       mutex_init(&nh->mutex);
+       if (init_srcu_struct(&nh->srcu) < 0)
+               BUG();
+       nh->head = NULL;
+}
+
+EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
+
 /**
  *     register_reboot_notifier - Register function to be called at reboot time
  *     @nb: Info about notifier function to be called
index 835fe28b87a8325c1cfb691de03dd7e2615ea943..cfc737bffe6deb8d5b2c97658b19e7917e296cce 100644 (file)
@@ -34,7 +34,7 @@
  * possible cpu).
  *
  * The sequence counters are for flush_scheduled_work().  It wants to wait
- * until until all currently-scheduled works are completed, but it doesn't
+ * until all currently-scheduled works are completed, but it doesn't
  * want to be livelocked by new, incoming ones.  So it waits until
  * remove_sequence is >= the insert_sequence which pertained when
  * flush_scheduled_work() was called.
index 2cc11faa4ff127aa20086acf83d749ec6865f7e3..a4b730a2180cc129a46df390c4707ee247cf012f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * lib/reed_solomon/rslib.c
+ * lib/reed_solomon/reed_solomon.c
  *
  * Overview:
  *   Generic Reed Solomon encoder / decoder library
index 5d88489ef2de39e43245aa5483daa8af4a8a9452..db7c55de92cdc2ded0583d1ccc5239bdb4828d00 100644 (file)
@@ -92,7 +92,7 @@ config HAVE_MEMORY_PRESENT
 
 #
 # SPARSEMEM_EXTREME (which is the default) does some bootmem
-# allocations when memory_present() is called.  If this can not
+# allocations when memory_present() is called.  If this cannot
 # be done on your architecture, select this option.  However,
 # statically allocating the mem_section[] array can potentially
 # consume vast quantities of .bss, so be careful.
@@ -104,7 +104,7 @@ config SPARSEMEM_STATIC
        def_bool n
 
 #
-# Architectecture platforms which require a two level mem_section in SPARSEMEM
+# Architecture platforms which require a two level mem_section in SPARSEMEM
 # must select this option. This is usually for architecture platforms with
 # an extremely sparse physical address space.
 #
index ec469235985d6e2cd89d39bf8bd40405f133e142..f789500406fe39bc7c3c558bb5dcb488084d3de7 100644 (file)
@@ -1139,11 +1139,11 @@ success:
 }
 
 /**
- * __generic_file_aio_read - generic filesystem read routine
+ * generic_file_aio_read - generic filesystem read routine
  * @iocb:      kernel I/O control block
  * @iov:       io vector request
  * @nr_segs:   number of segments in the iovec
- * @ppos:      current file position
+ * @pos:       current file position
  *
  * This is the "read()" routine for all filesystems
  * that can use the page cache directly.
index 7c7d03dbf73dc6953283553cb17ef0ee76ddab94..1d709ff528e1e91cd9bbbf086f119c5d4ba3154a 100644 (file)
@@ -364,6 +364,8 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
        pte_t *ptep;
        pte_t pte;
        struct page *page;
+       struct page *tmp;
+       LIST_HEAD(page_list);
 
        WARN_ON(!is_vm_hugetlb_page(vma));
        BUG_ON(start & ~HPAGE_MASK);
@@ -384,12 +386,16 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
                        continue;
 
                page = pte_page(pte);
-               put_page(page);
+               list_add(&page->lru, &page_list);
                add_mm_counter(mm, file_rss, (int) -(HPAGE_SIZE / PAGE_SIZE));
        }
 
        spin_unlock(&mm->page_table_lock);
        flush_tlb_range(vma, start, end);
+       list_for_each_entry_safe(page, tmp, &page_list, lru) {
+               list_del(&page->lru);
+               put_page(page);
+       }
 }
 
 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
index 365019599df8556c23d493f007a07dbf201add00..8bdde9508f3b80fc8ed5738e3716f6d2d0872c3c 100644 (file)
@@ -221,7 +221,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
  *     Allocate enough pages to cover @size from the page level
  *     allocator and map them into continguos kernel virtual space.
  *
- *     For tight cotrol over page level allocator and protection flags
+ *     For tight control over page level allocator and protection flags
  *     use __vmalloc() instead.
  */
 void *vmalloc(unsigned long size)
index c0d4ce144dec41130e552723c5b3ecd4dca1876a..a0f33905744978df4c961e0e29187f3cf1cef54c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * mm/page-writeback.c.
+ * mm/page-writeback.c
  *
  * Copyright (C) 2002, Linus Torvalds.
  *
index 4f59d90b81e65a314e0433dc61371b785b3df61f..a8c003e7b3d51ae97c1a443f0c8d2fb1989f57a4 100644 (file)
@@ -900,7 +900,8 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
                      int classzone_idx, int alloc_flags)
 {
        /* free_pages my go negative - that's OK */
-       long min = mark, free_pages = z->free_pages - (1 << order) + 1;
+       unsigned long min = mark;
+       long free_pages = z->free_pages - (1 << order) + 1;
        int o;
 
        if (alloc_flags & ALLOC_HIGH)
@@ -2050,8 +2051,8 @@ int __init early_pfn_to_nid(unsigned long pfn)
 
 /**
  * free_bootmem_with_active_regions - Call free_bootmem_node for each active range
- * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed
- * @max_low_pfn: The highest PFN that till be passed to free_bootmem_node
+ * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed.
+ * @max_low_pfn: The highest PFN that will be passed to free_bootmem_node
  *
  * If an architecture guarantees that all ranges registered with
  * add_active_ranges() contain no holes and may be freed, this
@@ -2081,11 +2082,11 @@ void __init free_bootmem_with_active_regions(int nid,
 
 /**
  * sparse_memory_present_with_active_regions - Call memory_present for each active range
- * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used
+ * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used.
  *
  * If an architecture guarantees that all ranges registered with
  * add_active_ranges() contain no holes and may be freed, this
- * this function may be used instead of calling memory_present() manually.
+ * function may be used instead of calling memory_present() manually.
  */
 void __init sparse_memory_present_with_active_regions(int nid)
 {
@@ -2155,14 +2156,14 @@ static void __init account_node_boundary(unsigned int nid,
 
 /**
  * get_pfn_range_for_nid - Return the start and end page frames for a node
- * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned
- * @start_pfn: Passed by reference. On return, it will have the node start_pfn
- * @end_pfn: Passed by reference. On return, it will have the node end_pfn
+ * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned.
+ * @start_pfn: Passed by reference. On return, it will have the node start_pfn.
+ * @end_pfn: Passed by reference. On return, it will have the node end_pfn.
  *
  * It returns the start and end page frame of a node based on information
  * provided by an arch calling add_active_range(). If called for a node
  * with no available memory, a warning is printed and the start and end
- * PFNs will be 0
+ * PFNs will be 0.
  */
 void __init get_pfn_range_for_nid(unsigned int nid,
                        unsigned long *start_pfn, unsigned long *end_pfn)
@@ -2215,7 +2216,7 @@ unsigned long __init zone_spanned_pages_in_node(int nid,
 
 /*
  * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
- * then all holes in the requested range will be accounted for
+ * then all holes in the requested range will be accounted for.
  */
 unsigned long __init __absent_pages_in_range(int nid,
                                unsigned long range_start_pfn,
@@ -2268,7 +2269,7 @@ unsigned long __init __absent_pages_in_range(int nid,
  * @start_pfn: The start PFN to start searching for holes
  * @end_pfn: The end PFN to stop searching for holes
  *
- * It returns the number of pages frames in memory holes within a range
+ * It returns the number of pages frames in memory holes within a range.
  */
 unsigned long __init absent_pages_in_range(unsigned long start_pfn,
                                                        unsigned long end_pfn)
@@ -2582,11 +2583,12 @@ void __init shrink_active_range(unsigned int nid, unsigned long old_end_pfn,
 
 /**
  * remove_all_active_ranges - Remove all currently registered regions
+ *
  * During discovery, it may be found that a table like SRAT is invalid
  * and an alternative discovery method must be used. This function removes
  * all currently registered regions.
  */
-void __init remove_all_active_ranges()
+void __init remove_all_active_ranges(void)
 {
        memset(early_node_map, 0, sizeof(early_node_map));
        nr_nodemap_entries = 0;
@@ -2636,7 +2638,7 @@ unsigned long __init find_min_pfn_for_node(unsigned long nid)
  * find_min_pfn_with_active_regions - Find the minimum PFN registered
  *
  * It returns the minimum PFN based on information provided via
- * add_active_range()
+ * add_active_range().
  */
 unsigned long __init find_min_pfn_with_active_regions(void)
 {
@@ -2647,7 +2649,7 @@ unsigned long __init find_min_pfn_with_active_regions(void)
  * find_max_pfn_with_active_regions - Find the maximum PFN registered
  *
  * It returns the maximum PFN based on information provided via
- * add_active_range()
+ * add_active_range().
  */
 unsigned long __init find_max_pfn_with_active_regions(void)
 {
@@ -2662,10 +2664,7 @@ unsigned long __init find_max_pfn_with_active_regions(void)
 
 /**
  * free_area_init_nodes - Initialise all pg_data_t and zone data
- * @arch_max_dma_pfn: The maximum PFN usable for ZONE_DMA
- * @arch_max_dma32_pfn: The maximum PFN usable for ZONE_DMA32
- * @arch_max_low_pfn: The maximum PFN usable for ZONE_NORMAL
- * @arch_max_high_pfn: The maximum PFN usable for ZONE_HIGHMEM
+ * @max_zone_pfn: an array of max PFNs for each zone
  *
  * This will call free_area_init_node() for each active node in the system.
  * Using the page ranges provided by add_active_range(), the size of each
@@ -2723,14 +2722,15 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
 #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 
 /**
- * set_dma_reserve - Account the specified number of pages reserved in ZONE_DMA
- * @new_dma_reserve - The number of pages to mark reserved
+ * set_dma_reserve - set the specified number of pages reserved in the first zone
+ * @new_dma_reserve: The number of pages to mark reserved
  *
  * The per-cpu batchsize and zone watermarks are determined by present_pages.
  * In the DMA zone, a significant percentage may be consumed by kernel image
  * and other unfreeable allocations which can skew the watermarks badly. This
- * function may optionally be used to account for unfreeable pages in
- * ZONE_DMA. The effect will be lower watermarks and smaller per-cpu batchsize
+ * function may optionally be used to account for unfreeable pages in the
+ * first zone (e.g., ZONE_DMA). The effect will be lower watermarks and
+ * smaller per-cpu batchsize.
  */
 void __init set_dma_reserve(unsigned long new_dma_reserve)
 {
@@ -2843,10 +2843,11 @@ static void setup_per_zone_lowmem_reserve(void)
        calculate_totalreserve_pages();
 }
 
-/*
- * setup_per_zone_pages_min - called when min_free_kbytes changes.  Ensures 
- *     that the pages_{min,low,high} values for each zone are set correctly 
- *     with respect to min_free_kbytes.
+/**
+ * setup_per_zone_pages_min - called when min_free_kbytes changes.
+ *
+ * Ensures that the pages_{min,low,high} values for each zone are set correctly
+ * with respect to min_free_kbytes.
  */
 void setup_per_zone_pages_min(void)
 {
index 3dbd6f4e74774be9fd1db7e19d581ae31b1f4cce..c23b99250df264572c5f71c8d61470d549e0469b 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3488,22 +3488,25 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
 }
 
 
+#ifdef CONFIG_DEBUG_SLAB
 void *__kmalloc(size_t size, gfp_t flags)
 {
-#ifndef CONFIG_DEBUG_SLAB
-       return __do_kmalloc(size, flags, NULL);
-#else
        return __do_kmalloc(size, flags, __builtin_return_address(0));
-#endif
 }
 EXPORT_SYMBOL(__kmalloc);
 
-#ifdef CONFIG_DEBUG_SLAB
 void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
 {
        return __do_kmalloc(size, flags, caller);
 }
 EXPORT_SYMBOL(__kmalloc_track_caller);
+
+#else
+void *__kmalloc(size_t size, gfp_t flags)
+{
+       return __do_kmalloc(size, flags, NULL);
+}
+EXPORT_SYMBOL(__kmalloc);
 #endif
 
 /**
index e14fa84ef39a2df08b2087259c110851bfcf1bcc..ace2aea69f1a834ca7526a1bfa4070205b82579e 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -11,7 +11,7 @@
  */
 void *__kzalloc(size_t size, gfp_t flags)
 {
-       void *ret = ____kmalloc(size, flags);
+       void *ret = kmalloc_track_caller(size, flags);
        if (ret)
                memset(ret, 0, size);
        return ret;
@@ -33,7 +33,7 @@ char *kstrdup(const char *s, gfp_t gfp)
                return NULL;
 
        len = strlen(s) + 1;
-       buf = ____kmalloc(len, gfp);
+       buf = kmalloc_track_caller(len, gfp);
        if (buf)
                memcpy(buf, s, len);
        return buf;
@@ -51,7 +51,7 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
 {
        void *p;
 
-       p = ____kmalloc(len, gfp);
+       p = kmalloc_track_caller(len, gfp);
        if (p)
                memcpy(p, src, len);
        return p;
index 1ac191ce564142b46cf46ec7655231d76aad093e..750ab6ed13fca56ca42581dd32f74912fd1b347c 100644 (file)
@@ -503,7 +503,7 @@ EXPORT_SYMBOL(__vmalloc);
  *     Allocate enough pages to cover @size from the page level
  *     allocator and map them into contiguous kernel virtual space.
  *
- *     For tight cotrol over page level allocator and protection flags
+ *     For tight control over page level allocator and protection flags
  *     use __vmalloc() instead.
  */
 void *vmalloc(unsigned long size)
@@ -542,7 +542,7 @@ EXPORT_SYMBOL(vmalloc_user);
  *     Allocate enough pages to cover @size from the page level
  *     allocator and map them into contiguous kernel virtual space.
  *
- *     For tight cotrol over page level allocator and protection flags
+ *     For tight control over page level allocator and protection flags
  *     use __vmalloc() instead.
  */
 void *vmalloc_node(unsigned long size, int node)
@@ -563,7 +563,7 @@ EXPORT_SYMBOL(vmalloc_node);
  *     the page level allocator and map them into contiguous and
  *     executable kernel virtual space.
  *
- *     For tight cotrol over page level allocator and protection flags
+ *     For tight control over page level allocator and protection flags
  *     use __vmalloc() instead.
  */
 
index c448c7f6fde2a002b7549076e3c4d98e83a1194c..3c23760c5827518769f14ea3eaaa8fefb1e73397 100644 (file)
@@ -156,7 +156,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 
        /* Get the DATA. Size must match skb_add_mtu(). */
        size = SKB_DATA_ALIGN(size);
-       data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+       data = kmalloc_track_caller(size + sizeof(struct skb_shared_info),
+                       gfp_mask);
        if (!data)
                goto nodata;
 
index 30af4a4dfcc82cb7d0f0646faa9be67c77ef24cc..d172a9804448d8c50ff75586fbb959a1f43e9b84 100644 (file)
@@ -64,7 +64,7 @@ config ASK_IP_FIB_HASH
 config IP_FIB_TRIE
        bool "FIB_TRIE"
        ---help---
-       Use new experimental LC-trie as FIB lookup algoritm. 
+       Use new experimental LC-trie as FIB lookup algorithm. 
         This improves lookup performance if you have a large
        number of routes.
 
@@ -526,7 +526,7 @@ config TCP_CONG_HYBLA
        ---help---
        TCP-Hybla is a sender-side only change that eliminates penalization of
        long-RTT, large-bandwidth connections, like when satellite legs are
-       involved, expecially when sharing a common bottleneck with normal
+       involved, especially when sharing a common bottleneck with normal
        terrestrial connections.
 
 config TCP_CONG_VEGAS
@@ -556,7 +556,7 @@ config TCP_CONG_LP
        default n
        ---help---
        TCP Low Priority (TCP-LP), a distributed algorithm whose goal is
-       to utiliza only the excess network bandwidth as compared to the
+       to utilize only the excess network bandwidth as compared to the
        ``fair share`` of bandwidth as targeted by TCP.
        See http://www-ece.rice.edu/networks/TCP-LP/
 
index cfe5c84742865c56c0e6b40702bdf54b14f4f752..cfb5d3de9c848c024f4219aa34fc0de77baa8332 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/net/inet/arp.c
+/* linux/net/ipv4/arp.c
  *
  * Version:    $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $
  *
index c9820bfc493a2517df0d3460504617c0aba45fd6..891b9355cf9666c3c41f9fb9e83bd2e03351b193 100644 (file)
@@ -81,7 +81,7 @@ config        IP_VS_PROTO_ESP
        bool "ESP load balancing support"
        depends on IP_VS
        ---help---
-         This option enables support for load balancing ESP (Encapsultion
+         This option enables support for load balancing ESP (Encapsulation
          Security Payload) transport protocol. Say Y if unsure.
 
 config IP_VS_PROTO_AH
@@ -204,7 +204,7 @@ config      IP_VS_SED
          connections to the server with the shortest expected delay. The 
          expected delay that the job will experience is (Ci + 1) / Ui if 
          sent to the ith server, in which Ci is the number of connections
-         on the the ith server and Ui is the fixed service rate (weight)
+         on the ith server and Ui is the fixed service rate (weight)
          of the ith server.
 
          If you want to compile it in kernel, say Y. To compile it as a
index a55b8ff70ded91bbeaa586558ad74824f5b93a4f..d88c292f118c6818027054debfc05db88e3f9f49 100644 (file)
@@ -373,7 +373,7 @@ config IP_NF_TARGET_ULOG
          daemon using netlink multicast sockets; unlike the LOG target
          which can only be viewed through syslog.
 
-         The apropriate userspace logging daemon (ulogd) may be obtained from
+         The appropriate userspace logging daemon (ulogd) may be obtained from
          <http://www.gnumonks.org/projects/ulogd/>
 
          To compile it as a module, choose M here.  If unsure, say N.
index a6ed2d22a6e6e8017bcd6e1f9816ee2d2fcbbf64..b36b9463f5a40e7cda66d09603c9f77bf3333c4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/net/sunrpc/auth_gss.c
+ * linux/net/sunrpc/auth_gss/auth_gss.c
  *
  * RPCSEC_GSS client authentication.
  * 
index 638c0b576203bab4fac5c0037cf1881e2c1c32e3..447d9aef46051ebc9fd810bc96b01e92113c61f1 100644 (file)
@@ -903,9 +903,9 @@ out_seq:
 struct gss_svc_data {
        /* decoded gss client cred: */
        struct rpc_gss_wire_cred        clcred;
-       /* pointer to the beginning of the procedure-specific results,
-        * which may be encrypted/checksummed in svcauth_gss_release: */
-       __be32                          *body_start;
+       /* save a pointer to the beginning of the encoded verifier,
+        * for use in encryption/checksumming in svcauth_gss_release: */
+       __be32                          *verf_start;
        struct rsc                      *rsci;
 };
 
@@ -968,7 +968,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
        if (!svcdata)
                goto auth_err;
        rqstp->rq_auth_data = svcdata;
-       svcdata->body_start = NULL;
+       svcdata->verf_start = NULL;
        svcdata->rsci = NULL;
        gc = &svcdata->clcred;
 
@@ -1097,6 +1097,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
                goto complete;
        case RPC_GSS_PROC_DATA:
                *authp = rpcsec_gsserr_ctxproblem;
+               svcdata->verf_start = resv->iov_base + resv->iov_len;
                if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
                        goto auth_err;
                rqstp->rq_cred = rsci->cred;
@@ -1110,7 +1111,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
                                        gc->gc_seq, rsci->mechctx))
                                goto auth_err;
                        /* placeholders for length and seq. number: */
-                       svcdata->body_start = resv->iov_base + resv->iov_len;
                        svc_putnl(resv, 0);
                        svc_putnl(resv, 0);
                        break;
@@ -1119,7 +1119,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
                                        gc->gc_seq, rsci->mechctx))
                                goto auth_err;
                        /* placeholders for length and seq. number: */
-                       svcdata->body_start = resv->iov_base + resv->iov_len;
                        svc_putnl(resv, 0);
                        svc_putnl(resv, 0);
                        break;
@@ -1147,6 +1146,32 @@ out:
        return ret;
 }
 
+u32 *
+svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd)
+{
+       u32 *p, verf_len;
+
+       p = gsd->verf_start;
+       gsd->verf_start = NULL;
+
+       /* If the reply stat is nonzero, don't wrap: */
+       if (*(p-1) != rpc_success)
+               return NULL;
+       /* Skip the verifier: */
+       p += 1;
+       verf_len = ntohl(*p++);
+       p += XDR_QUADLEN(verf_len);
+       /* move accept_stat to right place: */
+       memcpy(p, p + 2, 4);
+       /* Also don't wrap if the accept stat is nonzero: */
+       if (*p != rpc_success) {
+               resbuf->head[0].iov_len -= 2 * 4;
+               return NULL;
+       }
+       p++;
+       return p;
+}
+
 static inline int
 svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
 {
@@ -1160,17 +1185,9 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
        int integ_offset, integ_len;
        int stat = -EINVAL;
 
-       p = gsd->body_start;
-       gsd->body_start = NULL;
-       /* move accept_stat to right place: */
-       memcpy(p, p + 2, 4);
-       /* Don't wrap in failure case: */
-       /* Counting on not getting here if call was not even accepted! */
-       if (*p != rpc_success) {
-               resbuf->head[0].iov_len -= 2 * 4;
+       p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
+       if (p == NULL)
                goto out;
-       }
-       p++;
        integ_offset = (u8 *)(p + 1) - (u8 *)resbuf->head[0].iov_base;
        integ_len = resbuf->len - integ_offset;
        BUG_ON(integ_len % 4);
@@ -1191,7 +1208,6 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp)
                resbuf->tail[0].iov_base = resbuf->head[0].iov_base
                                                + resbuf->head[0].iov_len;
                resbuf->tail[0].iov_len = 0;
-               rqstp->rq_restailpage = 0;
                resv = &resbuf->tail[0];
        } else {
                resv = &resbuf->tail[0];
@@ -1223,24 +1239,16 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
        int offset;
        int pad;
 
-       p = gsd->body_start;
-       gsd->body_start = NULL;
-       /* move accept_stat to right place: */
-       memcpy(p, p + 2, 4);
-       /* Don't wrap in failure case: */
-       /* Counting on not getting here if call was not even accepted! */
-       if (*p != rpc_success) {
-               resbuf->head[0].iov_len -= 2 * 4;
+       p = svcauth_gss_prepare_to_wrap(resbuf, gsd);
+       if (p == NULL)
                return 0;
-       }
-       p++;
        len = p++;
        offset = (u8 *)p - (u8 *)resbuf->head[0].iov_base;
        *p++ = htonl(gc->gc_seq);
        inpages = resbuf->pages;
        /* XXX: Would be better to write some xdr helper functions for
         * nfs{2,3,4}xdr.c that place the data right, instead of copying: */
-       if (resbuf->tail[0].iov_base && rqstp->rq_restailpage == 0) {
+       if (resbuf->tail[0].iov_base) {
                BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
                                                        + PAGE_SIZE);
                BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base);
@@ -1258,7 +1266,6 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
                resbuf->tail[0].iov_base = resbuf->head[0].iov_base
                        + resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE;
                resbuf->tail[0].iov_len = 0;
-               rqstp->rq_restailpage = 0;
        }
        if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages))
                return -ENOMEM;
@@ -1282,7 +1289,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
        if (gc->gc_proc != RPC_GSS_PROC_DATA)
                goto out;
        /* Release can be called twice, but we only wrap once. */
-       if (gsd->body_start == NULL)
+       if (gsd->verf_start == NULL)
                goto out;
        /* normally not set till svc_send, but we need it here: */
        /* XXX: what for?  Do we mess it up the moment we call svc_putu32
index a99e67b164c1a2dec4b8cf1ded5dacd97d634ae8..c2c8bb20d07f7171aad6a74e9c4cf323fd4f03ca 100644 (file)
@@ -417,18 +417,15 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
        if (size > RPCSVC_MAXPAYLOAD)
                size = RPCSVC_MAXPAYLOAD;
        pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE;
-       rqstp->rq_argused = 0;
-       rqstp->rq_resused = 0;
        arghi = 0;
        BUG_ON(pages > RPCSVC_MAXPAGES);
        while (pages) {
                struct page *p = alloc_page(GFP_KERNEL);
                if (!p)
                        break;
-               rqstp->rq_argpages[arghi++] = p;
+               rqstp->rq_pages[arghi++] = p;
                pages--;
        }
-       rqstp->rq_arghi = arghi;
        return ! pages;
 }
 
@@ -438,14 +435,10 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
 static void
 svc_release_buffer(struct svc_rqst *rqstp)
 {
-       while (rqstp->rq_arghi)
-               put_page(rqstp->rq_argpages[--rqstp->rq_arghi]);
-       while (rqstp->rq_resused) {
-               if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
-                       continue;
-               put_page(rqstp->rq_respages[rqstp->rq_resused]);
-       }
-       rqstp->rq_argused = 0;
+       int i;
+       for (i=0; i<ARRAY_SIZE(rqstp->rq_pages); i++)
+               if (rqstp->rq_pages[i])
+                       put_page(rqstp->rq_pages[i]);
 }
 
 /*
@@ -651,23 +644,32 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
        unsigned long           flags;
        int                     i, error = 0, dummy;
 
-       progp = serv->sv_program;
-
-       dprintk("RPC: svc_register(%s, %s, %d)\n",
-               progp->pg_name, proto == IPPROTO_UDP? "udp" : "tcp", port);
-
        if (!port)
                clear_thread_flag(TIF_SIGPENDING);
 
-       for (i = 0; i < progp->pg_nvers; i++) {
-               if (progp->pg_vers[i] == NULL)
-                       continue;
-               error = rpc_register(progp->pg_prog, i, proto, port, &dummy);
-               if (error < 0)
-                       break;
-               if (port && !dummy) {
-                       error = -EACCES;
-                       break;
+       for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+               for (i = 0; i < progp->pg_nvers; i++) {
+                       if (progp->pg_vers[i] == NULL)
+                               continue;
+
+                       dprintk("RPC: svc_register(%s, %s, %d, %d)%s\n",
+                                       progp->pg_name,
+                                       proto == IPPROTO_UDP?  "udp" : "tcp",
+                                       port,
+                                       i,
+                                       progp->pg_vers[i]->vs_hidden?
+                                               " (but not telling portmap)" : "");
+
+                       if (progp->pg_vers[i]->vs_hidden)
+                               continue;
+
+                       error = rpc_register(progp->pg_prog, i, proto, port, &dummy);
+                       if (error < 0)
+                               break;
+                       if (port && !dummy) {
+                               error = -EACCES;
+                               break;
+                       }
                }
        }
 
@@ -697,7 +699,7 @@ svc_process(struct svc_rqst *rqstp)
        u32                     dir, prog, vers, proc;
        __be32                  auth_stat, rpc_stat;
        int                     auth_res;
-       __be32                  *accept_statp;
+       __be32                  *reply_statp;
 
        rpc_stat = rpc_success;
 
@@ -707,10 +709,10 @@ svc_process(struct svc_rqst *rqstp)
        /* setup response xdr_buf.
         * Initially it has just one page 
         */
-       svc_take_page(rqstp); /* must succeed */
+       rqstp->rq_resused = 1;
        resv->iov_base = page_address(rqstp->rq_respages[0]);
        resv->iov_len = 0;
-       rqstp->rq_res.pages = rqstp->rq_respages+1;
+       rqstp->rq_res.pages = rqstp->rq_respages + 1;
        rqstp->rq_res.len = 0;
        rqstp->rq_res.page_base = 0;
        rqstp->rq_res.page_len = 0;
@@ -738,7 +740,7 @@ svc_process(struct svc_rqst *rqstp)
                goto err_bad_rpc;
 
        /* Save position in case we later decide to reject: */
-       accept_statp = resv->iov_base + resv->iov_len;
+       reply_statp = resv->iov_base + resv->iov_len;
 
        svc_putnl(resv, 0);             /* ACCEPT */
 
@@ -886,7 +888,7 @@ err_bad_auth:
        dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat));
        serv->sv_stats->rpcbadauth++;
        /* Restore write pointer to location of accept status: */
-       xdr_ressize_check(rqstp, accept_statp);
+       xdr_ressize_check(rqstp, reply_statp);
        svc_putnl(resv, 1);     /* REJECT */
        svc_putnl(resv, 1);     /* AUTH_ERROR */
        svc_putnl(resv, ntohl(auth_stat));      /* status */
@@ -926,3 +928,18 @@ err_bad:
        svc_putnl(resv, ntohl(rpc_stat));
        goto sendit;
 }
+
+/*
+ * Return (transport-specific) limit on the rpc payload.
+ */
+u32 svc_max_payload(const struct svc_rqst *rqstp)
+{
+       int max = RPCSVC_MAXPAYLOAD_TCP;
+
+       if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM)
+               max = RPCSVC_MAXPAYLOAD_UDP;
+       if (rqstp->rq_server->sv_bufsz < max)
+               max = rqstp->rq_server->sv_bufsz;
+       return max;
+}
+EXPORT_SYMBOL_GPL(svc_max_payload);
index 40d41a2831d75bb1dc4d710212e742bb62fa3033..e1bd933629fe59316f21fbcd8738b21e687c60e3 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/hash.h>
 #include <linux/string.h>
+#include <net/sock.h>
 
 #define RPCDBG_FACILITY        RPCDBG_AUTH
 
@@ -375,6 +376,44 @@ void svcauth_unix_purge(void)
        cache_purge(&ip_map_cache);
 }
 
+static inline struct ip_map *
+ip_map_cached_get(struct svc_rqst *rqstp)
+{
+       struct ip_map *ipm = rqstp->rq_sock->sk_info_authunix;
+       if (ipm != NULL) {
+               if (!cache_valid(&ipm->h)) {
+                       /*
+                        * The entry has been invalidated since it was
+                        * remembered, e.g. by a second mount from the
+                        * same IP address.
+                        */
+                       rqstp->rq_sock->sk_info_authunix = NULL;
+                       cache_put(&ipm->h, &ip_map_cache);
+                       return NULL;
+               }
+               cache_get(&ipm->h);
+       }
+       return ipm;
+}
+
+static inline void
+ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm)
+{
+       struct svc_sock *svsk = rqstp->rq_sock;
+
+       if (svsk->sk_sock->type == SOCK_STREAM && svsk->sk_info_authunix == NULL)
+               svsk->sk_info_authunix = ipm;   /* newly cached, keep the reference */
+       else
+               cache_put(&ipm->h, &ip_map_cache);
+}
+
+void
+svcauth_unix_info_release(void *info)
+{
+       struct ip_map *ipm = info;
+       cache_put(&ipm->h, &ip_map_cache);
+}
+
 static int
 svcauth_unix_set_client(struct svc_rqst *rqstp)
 {
@@ -384,8 +423,10 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
        if (rqstp->rq_proc == 0)
                return SVC_OK;
 
-       ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
-                           rqstp->rq_addr.sin_addr);
+       ipm = ip_map_cached_get(rqstp);
+       if (ipm == NULL)
+               ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
+                                   rqstp->rq_addr.sin_addr);
 
        if (ipm == NULL)
                return SVC_DENIED;
@@ -400,7 +441,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
                case 0:
                        rqstp->rq_client = &ipm->m_client->h;
                        kref_get(&rqstp->rq_client->ref);
-                       cache_put(&ipm->h, &ip_map_cache);
+                       ip_map_cached_put(rqstp, ipm);
                        break;
        }
        return SVC_OK;
index cba85d195222e9603be9c29c68628b113fd5582a..b39e7e2b648f67020a7706314cf142e81f017793 100644 (file)
@@ -313,7 +313,7 @@ svc_sock_release(struct svc_rqst *rqstp)
 
        svc_release_skb(rqstp);
 
-       svc_free_allpages(rqstp);
+       svc_free_res_pages(rqstp);
        rqstp->rq_res.page_len = 0;
        rqstp->rq_res.page_base = 0;
 
@@ -412,7 +412,8 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
        /* send head */
        if (slen == xdr->head[0].iov_len)
                flags = 0;
-       len = kernel_sendpage(sock, rqstp->rq_respages[0], 0, xdr->head[0].iov_len, flags);
+       len = kernel_sendpage(sock, rqstp->rq_respages[0], 0,
+                                 xdr->head[0].iov_len, flags);
        if (len != xdr->head[0].iov_len)
                goto out;
        slen -= xdr->head[0].iov_len;
@@ -437,8 +438,9 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
        }
        /* send tail */
        if (xdr->tail[0].iov_len) {
-               result = kernel_sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage],
-                                            ((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1),
+               result = kernel_sendpage(sock, rqstp->rq_respages[0],
+                                            ((unsigned long)xdr->tail[0].iov_base)
+                                               & (PAGE_SIZE-1),
                                             xdr->tail[0].iov_len, 0);
 
                if (result > 0)
@@ -492,7 +494,12 @@ svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
        }
        spin_unlock(&serv->sv_lock);
        if (closesk)
+               /* Should unregister with portmap, but you cannot
+                * unregister just one protocol...
+                */
                svc_delete_socket(closesk);
+       else if (toclose)
+               return -ENOENT;
        return len;
 }
 EXPORT_SYMBOL(svc_sock_names);
@@ -703,9 +710,11 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
        if (len <= rqstp->rq_arg.head[0].iov_len) {
                rqstp->rq_arg.head[0].iov_len = len;
                rqstp->rq_arg.page_len = 0;
+               rqstp->rq_respages = rqstp->rq_pages+1;
        } else {
                rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len;
-               rqstp->rq_argused += (rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE;
+               rqstp->rq_respages = rqstp->rq_pages + 1 +
+                       (rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE;
        }
 
        if (serv->sv_stats)
@@ -946,7 +955,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
        struct svc_sock *svsk = rqstp->rq_sock;
        struct svc_serv *serv = svsk->sk_server;
        int             len;
-       struct kvec vec[RPCSVC_MAXPAGES];
+       struct kvec *vec;
        int pnum, vlen;
 
        dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
@@ -1044,15 +1053,17 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
        len = svsk->sk_reclen;
        set_bit(SK_DATA, &svsk->sk_flags);
 
+       vec = rqstp->rq_vec;
        vec[0] = rqstp->rq_arg.head[0];
        vlen = PAGE_SIZE;
        pnum = 1;
        while (vlen < len) {
-               vec[pnum].iov_base = page_address(rqstp->rq_argpages[rqstp->rq_argused++]);
+               vec[pnum].iov_base = page_address(rqstp->rq_pages[pnum]);
                vec[pnum].iov_len = PAGE_SIZE;
                pnum++;
                vlen += PAGE_SIZE;
        }
+       rqstp->rq_respages = &rqstp->rq_pages[pnum];
 
        /* Now receive data */
        len = svc_recvfrom(rqstp, vec, pnum, len);
@@ -1204,7 +1215,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
        struct svc_sock         *svsk =NULL;
        struct svc_serv         *serv = rqstp->rq_server;
        struct svc_pool         *pool = rqstp->rq_pool;
-       int                     len;
+       int                     len, i;
        int                     pages;
        struct xdr_buf          *arg;
        DECLARE_WAITQUEUE(wait, current);
@@ -1221,27 +1232,22 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
                        "svc_recv: service %p, wait queue active!\n",
                         rqstp);
 
-       /* Initialize the buffers */
-       /* first reclaim pages that were moved to response list */
-       svc_pushback_allpages(rqstp);
 
        /* now allocate needed pages.  If we get a failure, sleep briefly */
        pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE;
-       while (rqstp->rq_arghi < pages) {
-               struct page *p = alloc_page(GFP_KERNEL);
-               if (!p) {
-                       schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-                       continue;
+       for (i=0; i < pages ; i++)
+               while (rqstp->rq_pages[i] == NULL) {
+                       struct page *p = alloc_page(GFP_KERNEL);
+                       if (!p)
+                               schedule_timeout_uninterruptible(msecs_to_jiffies(500));
+                       rqstp->rq_pages[i] = p;
                }
-               rqstp->rq_argpages[rqstp->rq_arghi++] = p;
-       }
 
        /* Make arg->head point to first page and arg->pages point to rest */
        arg = &rqstp->rq_arg;
-       arg->head[0].iov_base = page_address(rqstp->rq_argpages[0]);
+       arg->head[0].iov_base = page_address(rqstp->rq_pages[0]);
        arg->head[0].iov_len = PAGE_SIZE;
-       rqstp->rq_argused = 1;
-       arg->pages = rqstp->rq_argpages + 1;
+       arg->pages = rqstp->rq_pages + 1;
        arg->page_base = 0;
        /* save at least one page for response */
        arg->page_len = (pages-2)*PAGE_SIZE;
@@ -1604,6 +1610,8 @@ svc_delete_socket(struct svc_sock *svsk)
                        sockfd_put(svsk->sk_sock);
                else
                        sock_release(svsk->sk_sock);
+               if (svsk->sk_info_authunix != NULL)
+                       svcauth_unix_info_release(svsk->sk_info_authunix);
                kfree(svsk);
        } else {
                spin_unlock_bh(&serv->sv_lock);
@@ -1699,6 +1707,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp)
        rqstp->rq_prot        = dr->prot;
        rqstp->rq_addr        = dr->addr;
        rqstp->rq_daddr       = dr->daddr;
+       rqstp->rq_respages    = rqstp->rq_pages;
        return dr->argslen<<2;
 }
 
index cac8f21a33924b0e02cf8ee9a471191ae3dda3ba..6a026f69b563e67cf098f110901b490a887bd8f0 100644 (file)
@@ -97,7 +97,7 @@ quiet_cmd_unifdef       = UNIFDEF $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
                                   | $(HDRSED) > $@ || :
 
 quiet_cmd_check                  = CHECK   $(patsubst $(INSTALL_HDR_PATH)/$(_dst)/.check.%,$(_dst)/%,$@)
-      cmd_check                  = $(srctree)/scripts/hdrcheck.sh              \
+      cmd_check                  = $(CONFIG_SHELL) $(srctree)/scripts/hdrcheck.sh \
                               $(INSTALL_HDR_PATH)/include $(subst /.check.,/,$@) $@
 
 quiet_cmd_remove         = REMOVE  $(_dst)/$@
index c9ca0c23bd9100f3b583c4a87b7a3e096ce324dc..00d1ad19b2cc8babe05a17190ca48c5029eae9a1 100755 (executable)
@@ -57,8 +57,8 @@ use strict;
 #      other functions are ignored.
 #
 #  -nofunction funcname
-#      If set, then only generate documentation for the other function(s).  All
-#      other functions are ignored. Cannot be used with -function together
+#      If set, then only generate documentation for the other function(s).
+#      Cannot be used together with -function
 #      (yes, that's a bug -- perl hackers can fix it 8))
 #
 #  c files - list of 'c' files to process
index 293dbd6246c14009244243aacadc6889df90a018..23b51047494ef0bd9673911979a049c7295d0b44 100644 (file)
@@ -112,7 +112,7 @@ config SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
          your distribution will provide these and enable the new controls
          in the kernel they also distribute.
 
-         Note that this option can be overriden at boot with the
+         Note that this option can be overridden at boot with the
          selinux_compat_net parameter, and after boot via
          /selinux/compat_net.  See Documentation/kernel-parameters.txt
          for details on this parameter.
@@ -122,7 +122,7 @@ config SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
          well as any conntrack helpers for protocols which you
          wish to control.
 
-         If you are unsure what do do here, select N.
+         If you are unsure what to do here, select N.
 
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX
        bool "NSA SELinux maximum supported policy format version"
index f3b3530402cb6251404b1210a76d74c5f609969b..cc2b9ab7f4e5355d490aeebff240240b2a9446f1 100644 (file)
@@ -643,7 +643,7 @@ config SOUND_PSS
          command line.
 
 config PSS_MIXER
-       bool "Enable PSS mixer (Beethoven ADSP-16 and other compatibile)"
+       bool "Enable PSS mixer (Beethoven ADSP-16 and other compatible)"
        depends on SOUND_PSS
        help
          Answer Y for Beethoven ADSP-16. You may try to say Y also for other
index 86811792002f82194783d8e191528ad49e34360c..2489bd6bb08561ab5e8cc296eca87d20427a354b 100644 (file)
@@ -15,71 +15,42 @@ obj-$(CONFIG_SOUND_HAL2)    += hal2.o
 obj-$(CONFIG_SOUND_AEDSP16)    += aedsp16.o
 obj-$(CONFIG_SOUND_PSS)                += pss.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_TRIX)       += trix.o ad1848.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_OPL3SA1)    += opl3sa.o ad1848.o uart401.o
 obj-$(CONFIG_SOUND_SSCAPE)     += sscape.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_MAD16)      += mad16.o ad1848.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_CS4232)     += cs4232.o uart401.o
 obj-$(CONFIG_SOUND_MSS)                += ad1848.o
 obj-$(CONFIG_SOUND_OPL3SA2)    += opl3sa2.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_PAS)                += pas2.o sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_SB)         += sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_KAHLUA)     += kahlua.o
-obj-$(CONFIG_SOUND_WAVEFRONT)  += wavefront.o
-obj-$(CONFIG_SOUND_MAUI)       += maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)     += mpu401.o
 obj-$(CONFIG_SOUND_UART6850)   += uart6850.o
-obj-$(CONFIG_SOUND_GUS)                += gus.o ad1848.o
 obj-$(CONFIG_SOUND_ADLIB)      += adlib_card.o opl3.o
 obj-$(CONFIG_SOUND_YM3812)     += opl3.o
 obj-$(CONFIG_SOUND_VMIDI)      += v_midi.o
 obj-$(CONFIG_SOUND_VIDC)       += vidc_mod.o
 obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
-obj-$(CONFIG_SOUND_SGALAXY)    += sgalaxy.o ad1848.o
 obj-$(CONFIG_SOUND_AD1816)     += ad1816.o
 obj-$(CONFIG_SOUND_AD1889)     += ad1889.o ac97_codec.o
 obj-$(CONFIG_SOUND_ACI_MIXER)  += aci.o
-obj-$(CONFIG_SOUND_AWE32_SYNTH)        += awe_wave.o
 
 obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx_audio.o ac97_codec.o
 ifeq ($(CONFIG_MIDI_VIA82CXXX),y)
   obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o
 endif
-obj-$(CONFIG_SOUND_YMFPCI)     += ymfpci.o ac97_codec.o
-ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y)
-  obj-$(CONFIG_SOUND_YMFPCI)    += opl3.o uart401.o
-endif
 obj-$(CONFIG_SOUND_MSNDCLAS)   += msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)    += msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)      += vwsnd.o
 obj-$(CONFIG_SOUND_NM256)      += nm256_audio.o ac97.o
 obj-$(CONFIG_SOUND_ICH)                += i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o
-obj-$(CONFIG_SOUND_CMPCI)      += cmpci.o
-ifeq ($(CONFIG_SOUND_CMPCI_FM),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o opl3.o
-endif
-ifeq ($(CONFIG_SOUND_CMPCI_MIDI),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o mpu401.o
-endif
-obj-$(CONFIG_SOUND_ES1370)     += es1370.o
 obj-$(CONFIG_SOUND_ES1371)     += es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)    += nec_vrc5477.o ac97_codec.o
-obj-$(CONFIG_SOUND_AU1000)     += au1000.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1550_AC97)        += au1550_ac97.o ac97_codec.o
-obj-$(CONFIG_SOUND_ESSSOLO1)   += esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)     += cs46xx.o ac97_codec.o
-obj-$(CONFIG_SOUND_MAESTRO)    += maestro.o
-obj-$(CONFIG_SOUND_MAESTRO3)   += maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)    += trident.o ac97_codec.o
-obj-$(CONFIG_SOUND_HARMONY)    += harmony.o
 obj-$(CONFIG_SOUND_EMU10K1)    += ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)        += swarm_cs4297a.o
-obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)      += btaudio.o
-obj-$(CONFIG_SOUND_ALI5455)    += ali5455.o ac97_codec.o
-obj-$(CONFIG_SOUND_FORTE)      += forte.o ac97_codec.o
 
-obj-$(CONFIG_SOUND_AD1980)     += ac97_plugin_ad1980.o ac97_codec.o
 obj-$(CONFIG_SOUND_WM97XX)     += ac97_plugin_wm97xx.o
 
 ifeq ($(CONFIG_MIDI_EMU10K1),y)
@@ -87,28 +58,25 @@ ifeq ($(CONFIG_MIDI_EMU10K1),y)
 endif
 
 obj-$(CONFIG_SOUND_EMU10K1)    += emu10k1/
-obj-$(CONFIG_SOUND_CS4281)     += cs4281/
 obj-$(CONFIG_DMASOUND)         += dmasound/
 
 # Declare multi-part drivers.
 
 sound-objs     :=                                                      \
-    dev_table.o soundcard.o sound_syms.o               \
-    audio.o audio_syms.o dmabuf.o                                      \
-    midi_syms.o midi_synth.o midibuf.o                                 \
-    sequencer.o sequencer_syms.o sound_timer.o sys_timer.o
+    dev_table.o soundcard.o            \
+    audio.o dmabuf.o                                   \
+    midi_synth.o midibuf.o                                     \
+    sequencer.o sound_timer.o sys_timer.o
 
-gus-objs       := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
 pas2-objs      := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
 sb-objs                := sb_card.o
 sb_lib-objs    := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
 vidc_mod-objs  := vidc.o vidc_fill.o
-wavefront-objs  := wavfront.o wf_midi.o yss225.o
 
 hostprogs-y    := bin2hex hex2hex
 
 # Files generated that shall be removed upon make clean
-clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \
+clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \
                pss_boot.h trix_boot.h
 
 # Firmware files that need translation
@@ -118,21 +86,6 @@ clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \
 # will be forced to be remade.
 #
 
-# Turtle Beach Maui / Tropez
-
-$(obj)/maui.o: $(obj)/maui_boot.h
-
-ifeq ($(CONFIG_MAUI_HAVE_BOOT),y)
-    $(obj)/maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) $(obj)/bin2hex
-       $(obj)/bin2hex -i maui_os < $< > $@
-else
-    $(obj)/maui_boot.h:
-       (                                                       \
-           echo 'static unsigned char * maui_os = NULL;';      \
-           echo 'static int maui_osLen = 0;';                  \
-       ) > $@
-endif
-
 # Turtle Beach MultiSound
 
 ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y)
index 3ba6d91e891d2aba0b87c48d4eda3f1c6011bdae..72cf4ed77937dac96bcda281c2b9a4470b4a2c8a 100644 (file)
@@ -112,25 +112,6 @@ ac97_init (struct ac97_hwint *dev)
     return 0;
 }
 
-/* Reset the mixer to the currently saved settings.  */
-int
-ac97_reset (struct ac97_hwint *dev)
-{
-    int x;
-
-    if (dev->reset_device (dev))
-       return -1;
-
-    /* Now set the registers back to their last-written values. */
-    for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) {
-       int regnum = mixerRegs[x].ac97_regnum;
-       int value = dev->last_written_mixer_values [regnum / 2];
-       if (value >= 0)
-           ac97_put_register (dev, regnum, value);
-    }
-    return 0;
-}
-
 /* Return the contents of register REG; use the cache if the value in it
    is valid.  Returns a negative error code on failure. */
 static int
@@ -441,7 +422,6 @@ EXPORT_SYMBOL(ac97_init);
 EXPORT_SYMBOL(ac97_set_values);
 EXPORT_SYMBOL(ac97_put_register);
 EXPORT_SYMBOL(ac97_mixer_ioctl);
-EXPORT_SYMBOL(ac97_reset);
 MODULE_LICENSE("GPL");
 
 \f
index 77d454ea3202e1d231f1b94e808c0e9cff331638..01837a9d7d6eff2baa6d9daea9f864c826f238ee 100644 (file)
@@ -192,9 +192,6 @@ extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value);
 extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd,
                             void __user * arg);
 
-/* Do a complete reset on the AC97 mixer, restoring all mixer registers to
-   the current values.  Normally used after an APM resume event.  */
-extern int ac97_reset (struct ac97_hwint *dev);
 #endif
 \f
 /*
index 972327c97644f29bd37c09d0de4639ea3f9fb56f..602db497929abd70d048d1d5215b0d869651ab5f 100644 (file)
@@ -1399,95 +1399,6 @@ unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
 
 EXPORT_SYMBOL(ac97_set_adc_rate);
 
-int ac97_save_state(struct ac97_codec *codec)
-{
-       return 0;       
-}
-
-EXPORT_SYMBOL(ac97_save_state);
-
-int ac97_restore_state(struct ac97_codec *codec)
-{
-       int i;
-       unsigned int left, right, val;
-
-       for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-               if (!supported_mixer(codec, i)) 
-                       continue;
-
-               val = codec->mixer_state[i];
-               right = val >> 8;
-               left = val  & 0xff;
-               codec->write_mixer(codec, i, left, right);
-       }
-       return 0;
-}
-
-EXPORT_SYMBOL(ac97_restore_state);
-
-/**
- *     ac97_register_driver    -       register a codec helper
- *     @driver: Driver handler
- *
- *     Register a handler for codecs matching the codec id. The handler
- *     attach function is called for all present codecs and will be 
- *     called when new codecs are discovered.
- */
-int ac97_register_driver(struct ac97_driver *driver)
-{
-       struct list_head *l;
-       struct ac97_codec *c;
-       
-       mutex_lock(&codec_mutex);
-       INIT_LIST_HEAD(&driver->list);
-       list_add(&driver->list, &codec_drivers);
-       
-       list_for_each(l, &codecs)
-       {
-               c = list_entry(l, struct ac97_codec, list);
-               if(c->driver != NULL || ((c->model ^ driver->codec_id) & driver->codec_mask))
-                       continue;
-               if(driver->probe(c, driver))
-                       continue;
-               c->driver = driver;
-       }
-       mutex_unlock(&codec_mutex);
-       return 0;
-}
-
-EXPORT_SYMBOL_GPL(ac97_register_driver);
-
-/**
- *     ac97_unregister_driver  -       unregister a codec helper
- *     @driver: Driver handler
- *
- *     Unregister a handler for codecs matching the codec id. The handler
- *     remove function is called for all matching codecs.
- */
-void ac97_unregister_driver(struct ac97_driver *driver)
-{
-       struct list_head *l;
-       struct ac97_codec *c;
-       
-       mutex_lock(&codec_mutex);
-       list_del_init(&driver->list);
-
-       list_for_each(l, &codecs)
-       {
-               c = list_entry(l, struct ac97_codec, list);
-               if (c->driver == driver) {
-                       driver->remove(c, driver);
-                       c->driver = NULL;
-               }
-       }
-       
-       mutex_unlock(&codec_mutex);
-}
-
-EXPORT_SYMBOL_GPL(ac97_unregister_driver);
-
 static int swap_headphone(int remove_master)
 {
        struct list_head *l;
diff --git a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c
deleted file mode 100644 (file)
index 24a9acd..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-    ac97_plugin_ad1980.c  Copyright (C) 2003 Red Hat, Inc. All rights reserved.
-
-   The contents of this file are subject to the Open Software License version 1.1
-   that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is 
-   included herein by reference. 
-   
-   Alternatively, the contents of this file may be used under the
-   terms of the GNU General Public License version 2 (the "GPL") as 
-   distributed in the kernel source COPYING file, in which
-   case the provisions of the GPL are applicable instead of the
-   above.  If you wish to allow the use of your version of this file
-   only under the terms of the GPL and not to allow others to use
-   your version of this file under the OSL, indicate your decision
-   by deleting the provisions above and replace them with the notice
-   and other provisions required by the GPL.  If you do not delete
-   the provisions above, a recipient may use your version of this
-   file under either the OSL or the GPL.
-   
-   Authors:    Alan Cox <alan@redhat.com>
-
-   This is an example codec plugin. This one switches the connections
-   around to match the setups some vendors use with audio switched to
-   non standard front connectors not the normal rear ones
-
-   This code primarily exists to demonstrate how to use the codec
-   interface
-
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/ac97_codec.h>
-
-/**
- *     ad1980_remove           -       codec remove callback
- *     @codec: The codec that is being removed
- *
- *     This callback occurs when an AC97 codec is being removed. A
- *     codec remove call will not occur for a codec during that codec
- *     probe callback.
- *
- *     Most drivers will need to lock their remove versus their 
- *     use of the codec after the probe function.
- */
-static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-       /* Nothing to do in the simple example */
-}
-
-
-/**
- *     ad1980_probe            -       codec found callback
- *     @codec: ac97 codec matching the idents
- *     @driver: ac97_driver it matched
- *
- *     This entry point is called when a codec is found which matches
- *     the driver. At the point it is called the codec is basically
- *     operational, mixer operations have been initialised and can
- *     be overriden. Called in process context. The field driver_private
- *     is available for the driver to use to store stuff.
- *
- *     The caller can claim the device by returning zero, or return
- *     a negative error code. 
- */
-static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-       u16 control;
-
-#define AC97_AD_MISC   0x76
-
-       /* Switch the inputs/outputs over (from Dell code) */
-       control = codec->codec_read(codec, AC97_AD_MISC);
-       codec->codec_write(codec, AC97_AD_MISC, control | 0x4420);
-       
-       /* We could refuse the device since we dont need to hang around,
-          but we will claim it */
-       return 0;
-}
-       
-static struct ac97_driver ad1980_driver = {
-       .codec_id       = 0x41445370,
-       .codec_mask     = 0xFFFFFFFF,
-       .name           = "AD1980 example",
-       .probe          = ad1980_probe,
-       .remove         = __devexit_p(ad1980_remove),
-};
-
-/**
- *     ad1980_exit             -       module exit path
- *
- *     Our module is being unloaded. At this point unregister_driver
- *     will call back our remove handler for any existing codecs. You
- *     may not unregister_driver from interrupt context or from a 
- *     probe/remove callback.
- */
-
-static void ad1980_exit(void)
-{
-       ac97_unregister_driver(&ad1980_driver);
-}
-
-/**
- *     ad1980_init             -       set up ad1980 handlers
- *
- *     After we call the register function it will call our probe
- *     function for each existing matching device before returning to us.
- *     Any devices appearing afterwards whose id's match the codec_id
- *     will also cause the probe function to be called.
- *     You may not register_driver from interrupt context or from a 
- *     probe/remove callback.
- */
-static int ad1980_init(void)
-{
-       return ac97_register_driver(&ad1980_driver);
-}
-
-module_init(ad1980_init);
-module_exit(ad1980_exit);
-MODULE_LICENSE("GPL");
index 3b45e11e5303ca7cccdc37f4ddf32f4eec1d72f3..257b7536fb18b505033e3a4233aa67187309f3cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/ad1848.c
+ * sound/oss/ad1848.c
  *
  * The low level driver for the AD1848/CS4248 codec chip which
  * is used for example in the MS Sound System.
@@ -195,6 +195,7 @@ static void     ad1848_halt(int dev);
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
@@ -2195,7 +2196,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
                printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
 }
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        unsigned char status;
        ad1848_info *devc;
@@ -2802,7 +2803,6 @@ EXPORT_SYMBOL(ad1848_detect);
 EXPORT_SYMBOL(ad1848_init);
 EXPORT_SYMBOL(ad1848_unload);
 EXPORT_SYMBOL(ad1848_control);
-EXPORT_SYMBOL(adintr);
 EXPORT_SYMBOL(probe_ms_sound);
 EXPORT_SYMBOL(attach_ms_sound);
 EXPORT_SYMBOL(unload_ms_sound);
index d0573b0239732edf59608863ef504523074544b8..b95ebe28d42609a15b78f96a26461278f334c8ab 100644 (file)
@@ -18,7 +18,6 @@ void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int
 int ad1848_detect (struct resource *ports, int *flags, int *osp);
 int ad1848_control(int cmd, int arg);
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy);
 void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner);
 
 int probe_ms_sound(struct address_info *hw_config, struct resource *ports);
index f9231c6cd4e1da24ce94a3d93eea315668fb6fde..2cf719b5fbbc51ac254eb0cba16817d92fe3322e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/ad1848_mixer.h
+ * sound/oss/ad1848_mixer.h
  *
  * Definitions for the mixer of AD1848 and compatible codecs.
  */
index 6414ceb8f0724c0ccb200d10cb61aa5ab983376b..c9a7c9b470decc57c2ff7f25dc9a618b1da9d109 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/adlib_card.c
+ * sound/oss/adlib_card.c
  *
  * Detection routine for the AdLib card.
  *
diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c
deleted file mode 100644 (file)
index 70dcd70..0000000
+++ /dev/null
@@ -1,3735 +0,0 @@
-/*
- *     ALI  ali5455 and friends ICH driver for Linux
- *     LEI HU <Lei_Hu@ali.com.tw>
- *
- *  Built from:
- *     drivers/sound/i810_audio
- *
- *     The ALi 5455 is similar but not quite identical to the Intel ICH
- *     series of controllers. Its easier to keep the driver separated from
- *     the i810 driver.
- *
- *     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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- *     ALi 5455 theory of operation
- *
- *     The chipset provides three DMA channels that talk to an AC97
- *     CODEC (AC97 is a digital/analog mixer standard). At its simplest
- *     you get 48Khz audio with basic volume and mixer controls. At the
- *     best you get rate adaption in the codec. We set the card up so
- *     that we never take completion interrupts but instead keep the card
- *     chasing its tail around a ring buffer. This is needed for mmap
- *     mode audio and happens to work rather well for non-mmap modes too.
- *
- *     The board has one output channel for PCM audio (supported) and
- *     a stereo line in and mono microphone input. Again these are normally
- *     locked to 48Khz only. Right now recording is not finished.
- *
- *     There is no midi support, no synth support. Use timidity. To get
- *     esd working you need to use esd -r 48000 as it won't probe 48KHz
- *     by default. mpg123 can't handle 48Khz only audio so use xmms.
- *
- *     If you need to force a specific rate set the clocking= option
- *
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#ifndef PCI_DEVICE_ID_ALI_5455
-#define PCI_DEVICE_ID_ALI_5455 0x5455
-#endif
-
-#ifndef PCI_VENDOR_ID_ALI
-#define PCI_VENDOR_ID_ALI      0x10b9
-#endif
-
-static int strict_clocking = 0;
-static unsigned int clocking = 0;
-static unsigned int codec_pcmout_share_spdif_locked = 0;
-static unsigned int codec_independent_spdif_locked = 0;
-static unsigned int controller_pcmout_share_spdif_locked = 0;
-static unsigned int controller_independent_spdif_locked = 0;
-static unsigned int globel = 0;
-
-#define ADC_RUNNING    1
-#define DAC_RUNNING    2
-#define CODEC_SPDIFOUT_RUNNING 8
-#define CONTROLLER_SPDIFOUT_RUNNING 4
-
-#define SPDIF_ENABLE_OUTPUT    4       /* bits 0,1 are PCM */
-
-#define ALI5455_FMT_16BIT      1
-#define ALI5455_FMT_STEREO     2
-#define ALI5455_FMT_MASK       3
-
-#define SPDIF_ON       0x0004
-#define SURR_ON                0x0010
-#define CENTER_LFE_ON  0x0020
-#define VOL_MUTED      0x8000
-
-
-#define ALI_SPDIF_OUT_CH_STATUS 0xbf
-/* the 810's array of pointers to data buffers */
-
-struct sg_item {
-#define BUSADDR_MASK   0xFFFFFFFE
-       u32 busaddr;
-#define CON_IOC        0x80000000      /* interrupt on completion */
-#define CON_BUFPAD     0x40000000      /* pad underrun with last sample, else 0 */
-#define CON_BUFLEN_MASK        0x0000ffff      /* buffer length in samples */
-       u32 control;
-};
-
-/* an instance of the ali channel */
-#define SG_LEN 32
-struct ali_channel {
-       /* these sg guys should probably be allocated
-          separately as nocache. Must be 8 byte aligned */
-       struct sg_item sg[SG_LEN];      /* 32*8 */
-       u32 offset;             /* 4 */
-       u32 port;               /* 4 */
-       u32 used;
-       u32 num;
-};
-
-/*
- * we have 3 separate dma engines.  pcm in, pcm out, and mic.
- * each dma engine has controlling registers.  These goofy
- * names are from the datasheet, but make it easy to write
- * code while leafing through it.
- */
-
-#define ENUM_ENGINE(PRE,DIG)                                                                   \
-enum {                                                                                         \
-       PRE##_BDBAR =   0x##DIG##0,             /* Buffer Descriptor list Base Address */       \
-       PRE##_CIV =     0x##DIG##4,             /* Current Index Value */                       \
-       PRE##_LVI =     0x##DIG##5,             /* Last Valid Index */                          \
-       PRE##_SR =      0x##DIG##6,             /* Status Register */                           \
-       PRE##_PICB =    0x##DIG##8,             /* Position In Current Buffer */                \
-       PRE##_CR =      0x##DIG##b              /* Control Register */                          \
-}
-
-ENUM_ENGINE(OFF, 0);           /* Offsets */
-ENUM_ENGINE(PI, 4);            /* PCM In */
-ENUM_ENGINE(PO, 5);            /* PCM Out */
-ENUM_ENGINE(MC, 6);            /* Mic In */
-ENUM_ENGINE(CODECSPDIFOUT, 7); /* CODEC SPDIF OUT  */
-ENUM_ENGINE(CONTROLLERSPDIFIN, A);     /* CONTROLLER SPDIF In */
-ENUM_ENGINE(CONTROLLERSPDIFOUT, B);    /* CONTROLLER SPDIF OUT */
-
-
-enum {
-       ALI_SCR = 0x00,         /* System Control Register */
-       ALI_SSR = 0x04,         /* System Status Register  */
-       ALI_DMACR = 0x08,       /* DMA Control Register    */
-       ALI_FIFOCR1 = 0x0c,     /* FIFO Control Register 1  */
-       ALI_INTERFACECR = 0x10, /* Interface Control Register */
-       ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */
-       ALI_INTERRUPTSR = 0x18, /* Interrupt  Status Register */
-       ALI_FIFOCR2 = 0x1c,     /* FIFO Control Register 2   */
-       ALI_CPR = 0x20,         /* Command Port Register     */
-       ALI_SPR = 0x24,         /* Status Port Register      */
-       ALI_FIFOCR3 = 0x2c,     /* FIFO Control Register 3  */
-       ALI_TTSR = 0x30,        /* Transmit Tag Slot Register */
-       ALI_RTSR = 0x34,        /* Receive Tag Slot  Register */
-       ALI_CSPSR = 0x38,       /* Command/Status Port Status Register */
-       ALI_CAS = 0x3c,         /* Codec Write Semaphore Register */
-       ALI_SPDIFCSR = 0xf8,    /* spdif channel status register  */
-       ALI_SPDIFICS = 0xfc     /* spdif interface control/status  */
-};
-
-// x-status register(x:pcm in ,pcm out, mic in,)
-/* interrupts for a dma engine */
-#define DMA_INT_FIFO           (1<<4)  /* fifo under/over flow */
-#define DMA_INT_COMPLETE       (1<<3)  /* buffer read/write complete and ioc set */
-#define DMA_INT_LVI            (1<<2)  /* last valid done */
-#define DMA_INT_CELV           (1<<1)  /* last valid is current */
-#define DMA_INT_DCH            (1)     /* DMA Controller Halted (happens on LVI interrupts) */ //not eqult intel
-#define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI)
-
-/* interrupts for the whole chip */// by interrupt status register finish
-
-#define INT_SPDIFOUT   (1<<23) /* controller spdif out INTERRUPT */
-#define INT_SPDIFIN   (1<<22)
-#define INT_CODECSPDIFOUT   (1<<19)
-#define INT_MICIN   (1<<18)
-#define INT_PCMOUT   (1<<17)
-#define INT_PCMIN   (1<<16)
-#define INT_CPRAIS   (1<<7)
-#define INT_SPRAIS   (1<<5)
-#define INT_GPIO    (1<<1)
-#define INT_MASK   (INT_SPDIFOUT|INT_CODECSPDIFOUT|INT_MICIN|INT_PCMOUT|INT_PCMIN)
-
-#define DRIVER_VERSION "0.02ac"
-
-/* magic numbers to protect our data structures */
-#define ALI5455_CARD_MAGIC             0x5072696E      /* "Prin" */
-#define ALI5455_STATE_MAGIC            0x63657373      /* "cess" */
-#define ALI5455_DMA_MASK               0xffffffff      /* DMA buffer mask for pci_alloc_consist */
-#define NR_HW_CH                       5       //I think 5 channel
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97                2
-
-/* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */
-/* stream at a minimum for this card to be happy */
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-/* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */
-/* values are one less than might be expected */
-static const unsigned sample_shift[] = { -1, 0, 0, 1 };
-
-#define ALI5455
-static char *card_names[] = {
-       "ALI 5455"
-};
-
-static struct pci_device_id ali_pci_tbl[] = {
-       {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5455,
-        PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI5455},
-       {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, ali_pci_tbl);
-
-#ifdef CONFIG_PM
-#define PM_SUSPENDED(card) (card->pm_suspended)
-#else
-#define PM_SUSPENDED(card) (0)
-#endif
-
-/* "software" or virtual channel, an instance of opened /dev/dsp */
-struct ali_state {
-       unsigned int magic;
-       struct ali_card *card;  /* Card info */
-
-       /* single open lock mechanism, only used for recording */
-       struct mutex open_mutex;
-       wait_queue_head_t open_wait;
-
-       /* file mode */
-       mode_t open_mode;
-
-       /* virtual channel number */
-       int virt;
-
-#ifdef CONFIG_PM
-       unsigned int pm_saved_dac_rate, pm_saved_adc_rate;
-#endif
-       struct dmabuf {
-               /* wave sample stuff */
-               unsigned int rate;
-               unsigned char fmt, enable, trigger;
-
-               /* hardware channel */
-               struct ali_channel *read_channel;
-               struct ali_channel *write_channel;
-               struct ali_channel *codec_spdifout_channel;
-               struct ali_channel *controller_spdifout_channel;
-
-               /* OSS buffer management stuff */
-               void *rawbuf;
-               dma_addr_t dma_handle;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-
-               /* our buffer acts like a circular ring */
-               unsigned hwptr; /* where dma last started, updated by update_ptr */
-               unsigned swptr; /* where driver last clear/filled, updated by read/write */
-               int count;      /* bytes to be consumed or been generated by dma machine */
-               unsigned total_bytes;   /* total bytes dmaed by hardware */
-
-               unsigned error; /* number of over/underruns */
-               wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */
-
-               /* redundant, but makes calculations easier */
-               /* what the hardware uses */
-               unsigned dmasize;
-               unsigned fragsize;
-               unsigned fragsamples;
-
-               /* what we tell the user to expect */
-               unsigned userfrags;
-               unsigned userfragsize;
-
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned update_flag;
-               unsigned ossfragsize;
-               unsigned ossmaxfrags;
-               unsigned subdivision;
-       } dmabuf;
-};
-
-
-struct ali_card {
-       struct ali_channel channel[5];
-       unsigned int magic;
-
-       /* We keep ali5455 cards in a linked list */
-       struct ali_card *next;
-
-       /* The ali has a certain amount of cross channel interaction
-          so we use a single per card lock */
-       spinlock_t lock;
-       spinlock_t ac97_lock;
-
-       /* PCI device stuff */
-       struct pci_dev *pci_dev;
-       u16 pci_id;
-#ifdef CONFIG_PM
-       u16 pm_suspended;
-       int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];
-#endif
-       /* soundcore stuff */
-       int dev_audio;
-
-       /* structures for abstraction of hardware facilities, codecs, banks and channels */
-       struct ac97_codec *ac97_codec[NR_AC97];
-       struct ali_state *states[NR_HW_CH];
-
-       u16 ac97_features;
-       u16 ac97_status;
-       u16 channels;
-
-       /* hardware resources */
-       unsigned long iobase;
-
-       u32 irq;
-
-       /* Function support */
-       struct ali_channel *(*alloc_pcm_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_rec_pcm_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_rec_mic_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_codec_spdifout_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_controller_spdifout_channel) (struct  ali_card *);
-       void (*free_pcm_channel) (struct ali_card *, int chan);
-
-       /* We have a *very* long init time possibly, so use this to block */
-       /* attempts to open our devices before we are ready (stops oops'es) */
-       int initializing;
-};
-
-
-static struct ali_card *devs = NULL;
-
-static int ali_open_mixdev(struct inode *inode, struct file *file);
-static int ali_ioctl_mixdev(struct inode *inode, struct file *file,
-                           unsigned int cmd, unsigned long arg);
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg);
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data);
-
-static struct ali_channel *ali_alloc_pcm_channel(struct ali_card *card)
-{
-       if (card->channel[1].used == 1)
-               return NULL;
-       card->channel[1].used = 1;
-       return &card->channel[1];
-}
-
-static struct ali_channel *ali_alloc_rec_pcm_channel(struct ali_card *card)
-{
-       if (card->channel[0].used == 1)
-               return NULL;
-       card->channel[0].used = 1;
-       return &card->channel[0];
-}
-
-static struct ali_channel *ali_alloc_rec_mic_channel(struct ali_card *card)
-{
-       if (card->channel[2].used == 1)
-               return NULL;
-       card->channel[2].used = 1;
-       return &card->channel[2];
-}
-
-static struct ali_channel *ali_alloc_codec_spdifout_channel(struct ali_card *card)
-{
-       if (card->channel[3].used == 1)
-               return NULL;
-       card->channel[3].used = 1;
-       return &card->channel[3];
-}
-
-static struct ali_channel *ali_alloc_controller_spdifout_channel(struct ali_card *card)
-{
-       if (card->channel[4].used == 1)
-               return NULL;
-       card->channel[4].used = 1;
-       return &card->channel[4];
-}
-static void ali_free_pcm_channel(struct ali_card *card, int channel)
-{
-       card->channel[channel].used = 0;
-}
-
-
-//add support  codec spdif out 
-static int ali_valid_spdif_rate(struct ac97_codec *codec, int rate)
-{
-       unsigned long id = 0L;
-
-       id = (ali_ac97_get(codec, AC97_VENDOR_ID1) << 16);
-       id |= ali_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff;
-       switch (id) {
-       case 0x41445361:        /* AD1886 */
-               if (rate == 48000) {
-                       return 1;
-               }
-               break;
-       case 0x414c4720:        /* ALC650 */
-               if (rate == 48000) {
-                       return 1;
-               }
-               break;
-       default:                /* all other codecs, until we know otherwiae */
-               if (rate == 48000 || rate == 44100 || rate == 32000) {
-                       return 1;
-               }
-               break;
-       }
-       return (0);
-}
-
-/* ali_set_spdif_output
- * 
- *  Configure the S/PDIF output transmitter. When we turn on
- *  S/PDIF, we turn off the analog output. This may not be
- *  the right thing to do.
- *
- *  Assumptions:
- *     The DSP sample rate must already be set to a supported
- *     S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort.
- */
-static void ali_set_spdif_output(struct ali_state *state, int slots,
-                                int rate)
-{
-       int vol;
-       int aud_reg;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 4)) {
-               state->card->ac97_status &= ~SPDIF_ON;
-       } else {
-               if (slots == -1) {      /* Turn off S/PDIF */
-                       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-
-                       /* If the volume wasn't muted before we turned on S/PDIF, unmute it */
-                       if (!(state->card->ac97_status & VOL_MUTED)) {
-                               aud_reg = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-                               ali_ac97_set(codec, AC97_MASTER_VOL_STEREO,
-                                            (aud_reg & ~VOL_MUTED));
-                       }
-                       state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON);
-                       return;
-               }
-
-               vol = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-               state->card->ac97_status = vol & VOL_MUTED;
-
-               /* Set S/PDIF transmitter sample rate */
-               aud_reg = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-               switch (rate) {
-               case 32000:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
-                       break;
-               case 44100:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
-                       break;
-               case 48000:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
-                       break;
-               default:
-                       /* turn off S/PDIF */
-                       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-                       state->card->ac97_status &= ~SPDIF_ON;
-                       return;
-               }
-
-               ali_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg);
-
-               aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-               aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_SPDIF;
-               ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-               aud_reg = ali_ac97_get(codec, AC97_POWER_CONTROL);
-               aud_reg |= 0x0002;
-               ali_ac97_set(codec, AC97_POWER_CONTROL, aud_reg);
-               udelay(1);
-
-               state->card->ac97_status |= SPDIF_ON;
-
-               /* Check to make sure the configuration is valid */
-               aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-               if (!(aud_reg & 0x0400)) {
-                       /* turn off S/PDIF */
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-                       state->card->ac97_status &= ~SPDIF_ON;
-                       return;
-               }
-               if (codec_independent_spdif_locked > 0) {
-                       aud_reg = ali_ac97_get(codec, 0x6a);
-                       ali_ac97_set(codec, 0x6a, (aud_reg & 0xefff));
-               }
-               /* Mute the analog output */
-               /* Should this only mute the PCM volume??? */
-       }
-}
-
-/* ali_set_dac_channels
- *
- *  Configure the codec's multi-channel DACs
- *
- *  The logic is backwards. Setting the bit to 1 turns off the DAC. 
- *
- *  What about the ICH? We currently configure it using the
- *  SNDCTL_DSP_CHANNELS ioctl.  If we're turnning on the DAC, 
- *  does that imply that we want the ICH set to support
- *  these channels?
- *  
- *  TODO:
- *    vailidate that the codec really supports these DACs
- *    before turning them on. 
- */
-static void ali_set_dac_channels(struct ali_state *state, int channel)
-{
-       int aud_reg;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-       aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK;
-       state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON);
-
-       switch (channel) {
-       case 2:         /* always enabled */
-               break;
-       case 4:
-               aud_reg &= ~AC97_EA_PRJ;
-               state->card->ac97_status |= SURR_ON;
-               break;
-       case 6:
-               aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK);
-               state->card->ac97_status |= SURR_ON | CENTER_LFE_ON;
-               break;
-       default:
-               break;
-       }
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-}
-
-/* set playback sample rate */
-static unsigned int ali_set_dac_rate(struct ali_state *state,
-                                    unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       u32 new_rate;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       /*
-        *      Adjust for misclocked crap
-        */
-
-       rate = (rate * clocking) / 48000;
-
-       if (strict_clocking && rate < 8000) {
-               rate = 8000;
-               dmabuf->rate = (rate * 48000) / clocking;
-       }
-
-       new_rate = ac97_set_dac_rate(codec, rate);
-       if (new_rate != rate) {
-               dmabuf->rate = (new_rate * 48000) / clocking;
-       }
-       rate = new_rate;
-       return dmabuf->rate;
-}
-
-/* set recording sample rate */
-static unsigned int ali_set_adc_rate(struct ali_state *state,
-                                    unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       u32 new_rate;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       /*
-        *      Adjust for misclocked crap
-        */
-
-       rate = (rate * clocking) / 48000;
-       if (strict_clocking && rate < 8000) {
-               rate = 8000;
-               dmabuf->rate = (rate * 48000) / clocking;
-       }
-
-       new_rate = ac97_set_adc_rate(codec, rate);
-
-       if (new_rate != rate) {
-               dmabuf->rate = (new_rate * 48000) / clocking;
-               rate = new_rate;
-       }
-       return dmabuf->rate;
-}
-
-/* set codec independent spdifout sample rate */
-static unsigned int ali_set_codecspdifout_rate(struct ali_state *state,
-                                              unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       return dmabuf->rate;
-}
-
-/* set  controller independent spdif out function sample rate */
-static void ali_set_spdifout_rate(struct ali_state *state,
-                                 unsigned int rate)
-{
-       unsigned char ch_st_sel;
-       unsigned short status_rate;
-
-       switch (rate) {
-       case 44100:
-               status_rate = 0;
-               break;
-       case 32000:
-               status_rate = 0x300;
-               break;
-       case 48000:
-       default:
-               status_rate = 0x200;
-               break;
-       }
-
-       ch_st_sel = inb(state->card->iobase + ALI_SPDIFICS) & ALI_SPDIF_OUT_CH_STATUS;  //select spdif_out
-
-       ch_st_sel |= 0x80;      //select right
-       outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-       outb(status_rate | 0x20, (state->card->iobase + ALI_SPDIFCSR + 2));
-
-       ch_st_sel &= (~0x80);   //select left
-       outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-       outw(status_rate | 0x10, (state->card->iobase + ALI_SPDIFCSR + 2));
-}
-
-/* get current playback/recording dma buffer pointer (byte offset from LBA),
-   called with spinlock held! */
-
-static inline unsigned ali_get_dma_addr(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned int civ, offset, port, port_picb;
-       unsigned int data;
-
-       if (!dmabuf->enable)
-               return 0;
-
-       if (rec == 1)
-               port = state->card->iobase + dmabuf->read_channel->port;
-       else if (rec == 2)
-               port = state->card->iobase + dmabuf->codec_spdifout_channel->port;
-       else if (rec == 3)
-               port = state->card->iobase + dmabuf->controller_spdifout_channel->port;
-       else
-               port = state->card->iobase + dmabuf->write_channel->port;
-
-       port_picb = port + OFF_PICB;
-
-       do {
-               civ = inb(port + OFF_CIV) & 31;
-               offset = inw(port_picb);
-               /* Must have a delay here! */
-               if (offset == 0)
-                       udelay(1);
-
-               /* Reread both registers and make sure that that total
-                * offset from the first reading to the second is 0.
-                * There is an issue with SiS hardware where it will count
-                * picb down to 0, then update civ to the next value,
-                * then set the new picb to fragsize bytes.  We can catch
-                * it between the civ update and the picb update, making
-                * it look as though we are 1 fragsize ahead of where we
-                * are.  The next to we get the address though, it will
-                * be back in thdelay is more than long enough
-                * that we won't have to worry about the chip still being
-                * out of sync with reality ;-)
-                */
-       } while (civ != (inb(port + OFF_CIV) & 31) || offset != inw(port_picb));
-
-       data = ((civ + 1) * dmabuf->fragsize - (2 * offset)) % dmabuf->dmasize;
-       if (inw(port_picb) == 0)
-               data -= 2048;
-
-       return data;
-}
-
-/* Stop recording (lock held) */
-static inline void __stop_adc(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       dmabuf->enable &= ~ADC_RUNNING;
-
-       outl((1 << 18) | (1 << 16), card->iobase + ALI_DMACR);
-       udelay(1);
-
-       outb(0, card->iobase + PI_CR);
-       while (inb(card->iobase + PI_CR) != 0);
-
-       // now clear any latent interrupt bits (like the halt bit)
-       outb(inb(card->iobase + PI_SR) | 0x001e, card->iobase + PI_SR);
-       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMIN, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_adc(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_adc(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_adc(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-
-       if (dmabuf->count < dmabuf->dmasize && dmabuf->ready
-           && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-               dmabuf->enable |= ADC_RUNNING;
-               outb((1 << 4) | (1 << 2), state->card->iobase + PI_CR);
-               if (state->card->channel[0].used == 1)
-                       outl(1, state->card->iobase + ALI_DMACR);       // DMA CONTROL REGISTRER
-               udelay(100);
-               if (state->card->channel[2].used == 1)
-                       outl((1 << 2), state->card->iobase + ALI_DMACR);        //DMA CONTROL REGISTER
-               udelay(100);
-       }
-}
-
-static void start_adc(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-
-       spin_lock_irqsave(&card->lock, flags);
-       __start_adc(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop playback (lock held) */
-static inline void __stop_dac(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       dmabuf->enable &= ~DAC_RUNNING;
-       outl(0x00020000, card->iobase + 0x08);
-       outb(0, card->iobase + PO_CR);
-       while (inb(card->iobase + PO_CR) != 0)
-               cpu_relax();
-
-       outb(inb(card->iobase + PO_SR) | 0x001e, card->iobase + PO_SR);
-
-       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMOUT, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_dac(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_dac(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_dac(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-           (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-               dmabuf->enable |= DAC_RUNNING;
-               outb((1 << 4) | (1 << 2), state->card->iobase + PO_CR);
-               outl((1 << 1), state->card->iobase + 0x08);     //dma control register
-       }
-}
-
-static void start_dac(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __start_dac(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop codec and controller spdif out  (lock held) */
-static inline void __stop_spdifout(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       if (codec_independent_spdif_locked > 0) {
-               dmabuf->enable &= ~CODEC_SPDIFOUT_RUNNING;
-               outl((1 << 19), card->iobase + 0x08);
-               outb(0, card->iobase + CODECSPDIFOUT_CR);
-
-               while (inb(card->iobase + CODECSPDIFOUT_CR) != 0)
-                       cpu_relax();
-
-               outb(inb(card->iobase + CODECSPDIFOUT_SR) | 0x001e, card->iobase + CODECSPDIFOUT_SR);
-               outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_CODECSPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       dmabuf->enable &= ~CONTROLLER_SPDIFOUT_RUNNING;
-                       outl((1 << 23), card->iobase + 0x08);
-                       outb(0, card->iobase + CONTROLLERSPDIFOUT_CR);
-                       while (inb(card->iobase + CONTROLLERSPDIFOUT_CR) != 0)
-                               cpu_relax();
-                       outb(inb(card->iobase + CONTROLLERSPDIFOUT_SR) | 0x001e, card->iobase + CONTROLLERSPDIFOUT_SR);
-                       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_SPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-               }
-       }
-}
-
-static void stop_spdifout(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_spdifout(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_spdifout(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-           (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-               if (codec_independent_spdif_locked > 0) {
-                       dmabuf->enable |= CODEC_SPDIFOUT_RUNNING;
-                       outb((1 << 4) | (1 << 2), state->card->iobase + CODECSPDIFOUT_CR);
-                       outl((1 << 3), state->card->iobase + 0x08);     //dma control register
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               dmabuf->enable |= CONTROLLER_SPDIFOUT_RUNNING;
-                               outb((1 << 4) | (1 << 2), state->card->iobase + CONTROLLERSPDIFOUT_CR);
-                               outl((1 << 7), state->card->iobase + 0x08);     //dma control register
-                       }
-               }
-       }
-}
-
-static void start_spdifout(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __start_spdifout(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/* allocate DMA buffer, playback , recording,spdif out  buffer should be allocated separately */
-static int alloc_dmabuf(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       void *rawbuf = NULL;
-       int order, size;
-       struct page *page, *pend;
-
-       /* If we don't have any oss frag params, then use our default ones */
-       if (dmabuf->ossmaxfrags == 0)
-               dmabuf->ossmaxfrags = 4;
-       if (dmabuf->ossfragsize == 0)
-               dmabuf->ossfragsize = (PAGE_SIZE << DMABUF_DEFAULTORDER) / dmabuf->ossmaxfrags;
-       size = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-
-       if (dmabuf->rawbuf && (PAGE_SIZE << dmabuf->buforder) == size)
-               return 0;
-       /* alloc enough to satisfy the oss params */
-       for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-               if ((PAGE_SIZE << order) > size)
-                       continue;
-               if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
-                                                  PAGE_SIZE << order,
-                                                  &dmabuf->dma_handle)))
-                       break;
-       }
-       if (!rawbuf)
-               return -ENOMEM;
-
-       dmabuf->ready = dmabuf->mapped = 0;
-       dmabuf->rawbuf = rawbuf;
-       dmabuf->buforder = order;
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (page = virt_to_page(rawbuf); page <= pend; page++)
-               SetPageReserved(page);
-       return 0;
-}
-
-/* free DMA buffer */
-static void dealloc_dmabuf(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct page *page, *pend;
-
-       if (dmabuf->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-               for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(state->card->pci_dev,
-                                   PAGE_SIZE << dmabuf->buforder,
-                                   dmabuf->rawbuf, dmabuf->dma_handle);
-       }
-       dmabuf->rawbuf = NULL;
-       dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ali_state *state, unsigned rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_channel *c = NULL;
-       struct sg_item *sg;
-       unsigned long flags;
-       int ret;
-       unsigned fragint;
-       int i;
-
-       spin_lock_irqsave(&state->card->lock, flags);
-       if (dmabuf->enable & DAC_RUNNING)
-               __stop_dac(state);
-       if (dmabuf->enable & ADC_RUNNING)
-               __stop_adc(state);
-       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-               __stop_spdifout(state);
-       if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-               __stop_spdifout(state);
-
-       dmabuf->total_bytes = 0;
-       dmabuf->count = dmabuf->error = 0;
-       dmabuf->swptr = dmabuf->hwptr = 0;
-       spin_unlock_irqrestore(&state->card->lock, flags);
-
-       /* allocate DMA buffer, let alloc_dmabuf determine if we are already
-        * allocated well enough or if we should replace the current buffer
-        * (assuming one is already allocated, if it isn't, then allocate it).
-        */
-       if ((ret = alloc_dmabuf(state)))
-               return ret;
-
-       /* FIXME: figure out all this OSS fragment stuff */
-       /* I did, it now does what it should according to the OSS API.  DL */
-       /* We may not have realloced our dmabuf, but the fragment size to
-        * fragment number ratio may have changed, so go ahead and reprogram
-        * things
-        */
-
-       dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder;
-       dmabuf->numfrag = SG_LEN;
-       dmabuf->fragsize = dmabuf->dmasize / dmabuf->numfrag;
-       dmabuf->fragsamples = dmabuf->fragsize >> 1;
-       dmabuf->userfragsize = dmabuf->ossfragsize;
-       dmabuf->userfrags = dmabuf->dmasize / dmabuf->ossfragsize;
-
-       memset(dmabuf->rawbuf, 0, dmabuf->dmasize);
-
-       if (dmabuf->ossmaxfrags == 4) {
-               fragint = 8;
-               dmabuf->fragshift = 2;
-       } else if (dmabuf->ossmaxfrags == 8) {
-               fragint = 4;
-               dmabuf->fragshift = 3;
-       } else if (dmabuf->ossmaxfrags == 16) {
-               fragint = 2;
-               dmabuf->fragshift = 4;
-       } else {
-               fragint = 1;
-               dmabuf->fragshift = 5;
-       }
-       /*
-        *      Now set up the ring 
-        */
-
-       if (rec == 1)
-               c = dmabuf->read_channel;
-       else if (rec == 2)
-               c = dmabuf->codec_spdifout_channel;
-       else if (rec == 3)
-               c = dmabuf->controller_spdifout_channel;
-       else if (rec == 0)
-               c = dmabuf->write_channel;
-       if (c != NULL) {
-               sg = &c->sg[0];
-               /*
-                *      Load up 32 sg entries and take an interrupt at half
-                *      way (we might want more interrupts later..) 
-                */
-               for (i = 0; i < dmabuf->numfrag; i++) {
-                       sg->busaddr =
-                           virt_to_bus(dmabuf->rawbuf +
-                                       dmabuf->fragsize * i);
-                       // the card will always be doing 16bit stereo
-                       sg->control = dmabuf->fragsamples;
-                       sg->control |= CON_BUFPAD;      //I modify
-                       // set us up to get IOC interrupts as often as needed to
-                       // satisfy numfrag requirements, no more
-                       if (((i + 1) % fragint) == 0) {
-                               sg->control |= CON_IOC;
-                       }
-                       sg++;
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               outb(2, state->card->iobase + c->port + OFF_CR);        /* reset DMA machine */
-               outl(virt_to_bus(&c->sg[0]), state->card->iobase + c->port + OFF_BDBAR);
-               outb(0, state->card->iobase + c->port + OFF_CIV);
-               outb(0, state->card->iobase + c->port + OFF_LVI);
-               spin_unlock_irqrestore(&state->card->lock, flags);
-       }
-       /* set the ready flag for the dma buffer */
-       dmabuf->ready = 1;
-       return 0;
-}
-
-static void __ali_update_lvi(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int x, port;
-       port = state->card->iobase;
-       if (rec == 1)
-               port += dmabuf->read_channel->port;
-       else if (rec == 2)
-               port += dmabuf->codec_spdifout_channel->port;
-       else if (rec == 3)
-               port += dmabuf->controller_spdifout_channel->port;
-       else if (rec == 0)
-               port += dmabuf->write_channel->port;
-       /* if we are currently stopped, then our CIV is actually set to our
-        * *last* sg segment and we are ready to wrap to the next.  However,
-        * if we set our LVI to the last sg segment, then it won't wrap to
-        * the next sg segment, it won't even get a start.  So, instead, when
-        * we are stopped, we set both the LVI value and also we increment
-        * the CIV value to the next sg segment to be played so that when
-        * we call start_{dac,adc}, things will operate properly
-        */
-       if (!dmabuf->enable && dmabuf->ready) {
-               if (rec && dmabuf->count < dmabuf->dmasize && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                       __start_adc(state);
-                       while (! (inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                               cpu_relax();
-               } else if (!rec && dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                       __start_dac(state);
-                       while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                               cpu_relax();
-               } else if (rec && dmabuf->count && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                       if (codec_independent_spdif_locked > 0) {
-                               // outb((inb(port+OFF_CIV))&31, port+OFF_LVI);
-                               outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                               __start_spdifout(state);
-                               while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                                       cpu_relax();
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                                       __start_spdifout(state);
-                                       while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                                               cpu_relax();
-                               }
-                       }
-               }
-       }
-
-       /* swptr - 1 is the tail of our transfer */
-       x = (dmabuf->dmasize + dmabuf->swptr - 1) % dmabuf->dmasize;
-       x /= dmabuf->fragsize;
-       outb(x, port + OFF_LVI);
-}
-
-static void ali_update_lvi(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       if (!dmabuf->ready)
-               return;
-       spin_lock_irqsave(&state->card->lock, flags);
-       __ali_update_lvi(state, rec);
-       spin_unlock_irqrestore(&state->card->lock, flags);
-}
-
-/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
-static void ali_update_ptr(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned hwptr;
-       int diff;
-       
-       /* error handling and process wake up for DAC */
-       if (dmabuf->enable == ADC_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 1);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count += diff;
-               if (dmabuf->count > dmabuf->dmasize) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a read */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + PI_CIV) & 31) != (inb(state->card->iobase + PI_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on read\n");
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count > dmabuf->userfragsize)
-                       wake_up(&dmabuf->wait);
-       }
-       /* error handling and process wake up for DAC */
-       if (dmabuf->enable == DAC_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 0);
-               diff =
-                   (dmabuf->dmasize + hwptr -
-                    dmabuf->hwptr) % dmabuf->dmasize;
-#if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP)
-               printk("DAC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
-#endif
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + PO_CIV) & 31) != (inb(state->card->iobase + PO_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-                               printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n",
-                                                       inb(state->card->iobase + PO_CIV) & 31,
-                                                       inb(state->card->iobase + PO_LVI) & 31, 
-                                                       dmabuf->hwptr,
-                                                       dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-
-       /* error handling and process wake up for CODEC SPDIF OUT */
-       if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 2);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-                               printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n", 
-                                       inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31,
-                                       inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31,
-                                       dmabuf->hwptr, dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-       /* error handling and process wake up for CONTROLLER SPDIF OUT */
-       if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 3);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31)) {
-                               printk(KERN_WARNING
-                                      "ali_audio: DMA overrun on write\n");
-                               printk("ali_audio: CIV %d, LVI %d, hwptr %x, "
-                                       "count %d\n",
-                                               inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31,
-                                               inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31,
-                                               dmabuf->hwptr, dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-}
-
-static inline int ali_get_free_write_space(struct
-                                          ali_state
-                                          *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int free;
-
-       if (dmabuf->count < 0) {
-               dmabuf->count = 0;
-               dmabuf->swptr = dmabuf->hwptr;
-       }
-       free = dmabuf->dmasize - dmabuf->swptr;
-       if ((dmabuf->count + free) > dmabuf->dmasize){
-               free = dmabuf->dmasize - dmabuf->count;
-       }
-       return free;
-}
-
-static inline int ali_get_available_read_data(struct
-                                             ali_state
-                                             *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int avail;
-       ali_update_ptr(state);
-       // catch overruns during record
-       if (dmabuf->count > dmabuf->dmasize) {
-               dmabuf->count = dmabuf->dmasize;
-               dmabuf->swptr = dmabuf->hwptr;
-       }
-       avail = dmabuf->count;
-       avail -= (dmabuf->hwptr % dmabuf->fragsize);
-       if (avail < 0)
-               return (0);
-       return (avail);
-}
-
-static int drain_dac(struct ali_state *state, int signals_allowed)
-{
-
-       DECLARE_WAITQUEUE(wait, current);
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned long tmo;
-       int count;
-       if (!dmabuf->ready)
-               return 0;
-       if (dmabuf->mapped) {
-               stop_dac(state);
-               return 0;
-       }
-       add_wait_queue(&dmabuf->wait, &wait);
-       for (;;) {
-
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               count = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               if (count <= 0)
-                       break;
-               /* 
-                * This will make sure that our LVI is correct, that our
-                * pointer is updated, and that the DAC is running.  We
-                * have to force the setting of dmabuf->trigger to avoid
-                * any possible deadlocks.
-                */
-               if (!dmabuf->enable) {
-                       dmabuf->trigger = PCM_ENABLE_OUTPUT;
-                       ali_update_lvi(state, 0);
-               }
-               if (signal_pending(current) && signals_allowed) {
-                       break;
-               }
-
-               /* It seems that we have to set the current state to
-                * TASK_INTERRUPTIBLE every time to make the process
-                * really go to sleep.  This also has to be *after* the
-                * update_ptr() call because update_ptr is likely to
-                * do a wake_up() which will unset this before we ever
-                * try to sleep, resuling in a tight loop in this code
-                * instead of actually sleeping and waiting for an
-                * interrupt to wake us up!
-                */
-               set_current_state(TASK_INTERRUPTIBLE);
-               /*
-                * set the timeout to significantly longer than it *should*
-                * take for the DAC to drain the DMA buffer
-                */
-               tmo = (count * HZ) / (dmabuf->rate);
-               if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                       printk(KERN_ERR "ali_audio: drain_dac, dma timeout?\n");
-                       count = 0;
-                       break;
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &wait);
-       if (count > 0 && signal_pending(current) && signals_allowed)
-               return -ERESTARTSYS;
-       stop_dac(state);
-       return 0;
-}
-
-
-static int drain_spdifout(struct ali_state *state, int signals_allowed)
-{
-
-       DECLARE_WAITQUEUE(wait, current);
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned long tmo;
-       int count;
-       if (!dmabuf->ready)
-               return 0;
-       if (dmabuf->mapped) {
-               stop_spdifout(state);
-               return 0;
-       }
-       add_wait_queue(&dmabuf->wait, &wait);
-       for (;;) {
-
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               count = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               if (count <= 0)
-                       break;
-               /* 
-                * This will make sure that our LVI is correct, that our
-                * pointer is updated, and that the DAC is running.  We
-                * have to force the setting of dmabuf->trigger to avoid
-                * any possible deadlocks.
-                */
-               if (!dmabuf->enable) {
-                       if (codec_independent_spdif_locked > 0) {
-                               dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                               ali_update_lvi(state, 2);
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 3);
-                               }
-                       }
-               }
-               if (signal_pending(current) && signals_allowed) {
-                       break;
-               }
-
-               /* It seems that we have to set the current state to
-                * TASK_INTERRUPTIBLE every time to make the process
-                * really go to sleep.  This also has to be *after* the
-                * update_ptr() call because update_ptr is likely to
-                * do a wake_up() which will unset this before we ever
-                * try to sleep, resuling in a tight loop in this code
-                * instead of actually sleeping and waiting for an
-                * interrupt to wake us up!
-                */
-               set_current_state(TASK_INTERRUPTIBLE);
-               /*
-                * set the timeout to significantly longer than it *should*
-                * take for the DAC to drain the DMA buffer
-                */
-               tmo = (count * HZ) / (dmabuf->rate);
-               if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                       printk(KERN_ERR "ali_audio: drain_spdifout, dma timeout?\n");
-                       count = 0;
-                       break;
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &wait);
-       if (count > 0 && signal_pending(current) && signals_allowed)
-               return -ERESTARTSYS;
-       stop_spdifout(state);
-       return 0;
-}
-
-static void ali_channel_interrupt(struct ali_card *card)
-{
-       int i, count;
-       
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               struct ali_channel *c = NULL;
-               struct dmabuf *dmabuf;
-               unsigned long port = card->iobase;
-               u16 status;
-               if (!state)
-                       continue;
-               if (!state->dmabuf.ready)
-                       continue;
-               dmabuf = &state->dmabuf;
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                               c = dmabuf->codec_spdifout_channel;
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       c = dmabuf->controller_spdifout_channel;
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING) {
-                                       c = dmabuf->write_channel;
-                               } else if (dmabuf->enable & ADC_RUNNING) {
-                                       c = dmabuf->read_channel;
-                               } else
-                                       continue;
-                       }
-               }
-               port += c->port;
-
-               status = inw(port + OFF_SR);
-
-               if (status & DMA_INT_COMPLETE) {
-                       /* only wake_up() waiters if this interrupt signals
-                        * us being beyond a userfragsize of data open or
-                        * available, and ali_update_ptr() does that for
-                        * us
-                        */
-                       ali_update_ptr(state);
-               }
-
-               if (status & DMA_INT_LVI) {
-                       ali_update_ptr(state);
-                       wake_up(&dmabuf->wait);
-
-                       if (dmabuf->enable & DAC_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & ADC_RUNNING)
-                               count = dmabuf->dmasize - dmabuf->count;
-                       else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else count = 0;
-
-                       if (count > 0) {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       outl((1 << 1), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                               outl((1 << 3), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       outl((1 << 7), state->card->iobase + ALI_DMACR);
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       __stop_dac(state);
-                               if (dmabuf->enable & ADC_RUNNING)
-                                       __stop_adc(state);
-                               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               dmabuf->enable = 0;
-                               wake_up(&dmabuf->wait);
-                       }
-
-               }
-               if (!(status & DMA_INT_DCH)) {
-                       ali_update_ptr(state);
-                       wake_up(&dmabuf->wait);
-                       if (dmabuf->enable & DAC_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & ADC_RUNNING)
-                               count = dmabuf->dmasize - dmabuf->count;
-                       else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else
-                               count = 0;
-
-                       if (count > 0) {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       outl((1 << 1), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       outl((1 << 3), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       outl((1 << 7), state->card->iobase + ALI_DMACR);
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       __stop_dac(state);
-                               if (dmabuf->enable & ADC_RUNNING)
-                                       __stop_adc(state);
-                               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               dmabuf->enable = 0;
-                               wake_up(&dmabuf->wait);
-                       }
-               }
-               outw(status & DMA_INT_MASK, port + OFF_SR);
-       }
-}
-
-static irqreturn_t ali_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct ali_card *card = (struct ali_card *) dev_id;
-       u32 status;
-       u16 status2;
-
-       spin_lock(&card->lock);
-       status = inl(card->iobase + ALI_INTERRUPTSR);
-       if (!(status & INT_MASK)) {
-               spin_unlock(&card->lock);
-               return IRQ_NONE;                /* not for us */
-       }
-
-       if (codec_independent_spdif_locked > 0) {
-               if (globel == 0) {
-                       globel += 1;
-                       status2 = inw(card->iobase + 0x76);
-                       outw(status2 | 0x000c, card->iobase + 0x76);
-               } else {
-                       if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-                               ali_channel_interrupt(card);
-               }
-       } else {
-               if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-                       ali_channel_interrupt(card);
-       }
-
-       /* clear 'em */
-       outl(status & INT_MASK, card->iobase + ALI_INTERRUPTSR);
-       spin_unlock(&card->lock);
-       return IRQ_HANDLED;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is
-   waiting to be copied to the user's buffer.  It is filled by the dma
-   machine and drained by this loop. */
-
-static ssize_t ali_read(struct file *file, char __user *buffer,
-                       size_t count, loff_t * ppos)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state ? state->card : NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;
-       DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-       printk("ali_audio: ali_read called, count = %d\n", count);
-#endif
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (dmabuf->enable & DAC_RUNNING)
-               return -ENODEV;
-       if (!dmabuf->read_channel) {
-               dmabuf->ready = 0;
-               dmabuf->read_channel = card->alloc_rec_pcm_channel(card);
-               if (!dmabuf->read_channel) {
-                       return -EBUSY;
-               }
-       }
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&dmabuf->wait, &waita);
-       while (count > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               swptr = dmabuf->swptr;
-               cnt = ali_get_available_read_data(state);
-               // this is to make the copy_to_user simpler below
-               if (cnt > (dmabuf->dmasize - swptr))
-                       cnt = dmabuf->dmasize - swptr;
-               spin_unlock_irqrestore(&card->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               /* Lop off the last two bits to force the code to always
-                * write in full samples.  This keeps software that sets
-                * O_NONBLOCK but doesn't check the return value of the
-                * write call from getting things out of state where they
-                * think a full 4 byte sample was written when really only
-                * a portion was, resulting in odd sound and stereo
-                * hysteresis.
-                */
-               cnt &= ~0x3;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       /*
-                        * Don't let us deadlock.  The ADC won't start if
-                        * dmabuf->trigger isn't set.  A call to SETTRIGGER
-                        * could have turned it off after we set it to on
-                        * previously.
-                        */
-                       dmabuf->trigger = PCM_ENABLE_INPUT;
-                       /*
-                        * This does three things.  Updates LVI to be correct,
-                        * makes sure the ADC is running, and updates the
-                        * hwptr.
-                        */
-                       ali_update_lvi(state, 1);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto done;
-                       }
-                       /* Set the timeout to how long it would take to fill
-                        * two of our buffers.  If we haven't been woke up
-                        * by then, then we know something is wrong.
-                        */
-                       tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-                           
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer overrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                               printk(KERN_ERR
-                                      "ali_audio: recording schedule timeout, "
-                                      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      dmabuf->dmasize, dmabuf->fragsize,
-                                      dmabuf->count, dmabuf->hwptr,
-                                      dmabuf->swptr);
-                               /* a buffer overrun, we delay the recovery until next time the
-                                  while loop begin and we REALLY have space to record */
-                       }
-                       if (signal_pending(current)) {
-                               ret = ret ? ret : -ERESTARTSYS;
-                               goto done;
-                       }
-                       continue;
-               }
-
-               if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto done;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-               spin_lock_irqsave(&card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       continue;
-               }
-               dmabuf->swptr = swptr;
-               dmabuf->count -= cnt;
-               spin_unlock_irqrestore(&card->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-done:
-       ali_update_lvi(state, 1);
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-       return ret;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
-   the soundcard.  it is drained by the dma machine and filled by this loop. */
-static ssize_t ali_write(struct file *file,
-                        const char __user *buffer, size_t count, loff_t * ppos)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state ? state->card : NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr = 0;
-       int cnt, x;
-       DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-       printk("ali_audio: ali_write called, count = %d\n", count);
-#endif
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (dmabuf->enable & ADC_RUNNING)
-               return -ENODEV;
-       if (codec_independent_spdif_locked > 0) {
-               if (!dmabuf->codec_spdifout_channel) {
-                       dmabuf->ready = 0;
-                       dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card);
-                       if (!dmabuf->codec_spdifout_channel)
-                               return -EBUSY;
-               }
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       if (!dmabuf->controller_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card);
-                               if (!dmabuf->controller_spdifout_channel)
-                                       return -EBUSY;
-                       }
-               } else {
-                       if (!dmabuf->write_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->write_channel =
-                                   card->alloc_pcm_channel(card);
-                               if (!dmabuf->write_channel)
-                                       return -EBUSY;
-                       }
-               }
-       }
-
-       if (codec_independent_spdif_locked > 0) {
-               if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-                       return ret;
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-                               return ret;
-               } else {
-
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-                               return ret;
-               }
-       }
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&dmabuf->wait, &waita);
-       while (count > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-
-               swptr = dmabuf->swptr;
-               cnt = ali_get_free_write_space(state);
-               /* Bound the maximum size to how much we can copy to the
-                * dma buffer before we hit the end.  If we have more to
-                * copy then it will get done in a second pass of this
-                * loop starting from the beginning of the buffer.
-                */
-               if (cnt > (dmabuf->dmasize - swptr))
-                       cnt = dmabuf->dmasize - swptr;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG2
-               printk(KERN_INFO
-                      "ali_audio: ali_write: %d bytes available space\n",
-                      cnt);
-#endif
-               if (cnt > count)
-                       cnt = count;
-               /* Lop off the last two bits to force the code to always
-                * write in full samples.  This keeps software that sets
-                * O_NONBLOCK but doesn't check the return value of the
-                * write call from getting things out of state where they
-                * think a full 4 byte sample was written when really only
-                * a portion was, resulting in odd sound and stereo
-                * hysteresis.
-                */
-               cnt &= ~0x3;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       // There is data waiting to be played
-                       /*
-                        * Force the trigger setting since we would
-                        * deadlock with it set any other way
-                        */
-                       if (codec_independent_spdif_locked > 0) {
-                               dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                               ali_update_lvi(state, 2);
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 3);
-                               } else {
-
-                                       dmabuf->trigger = PCM_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 0);
-                               }
-                       }
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto ret;
-                       }
-                       /* Not strictly correct but works */
-                       tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer underrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                          
-                       /* FIXME - do timeout handling here !! */
-                       schedule_timeout(tmo >= 2 ? tmo : 2);
-
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto ret;
-                       }
-                       continue;
-               }
-               if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto ret;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       continue;
-               }
-
-               dmabuf->swptr = swptr;
-               dmabuf->count += cnt;
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-       }
-       if (swptr % dmabuf->fragsize) {
-               x = dmabuf->fragsize - (swptr % dmabuf->fragsize);
-               memset(dmabuf->rawbuf + swptr, '\0', x);
-       }
-ret:
-       if (codec_independent_spdif_locked > 0) {
-               ali_update_lvi(state, 2);
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       ali_update_lvi(state, 3);
-               } else {
-                       ali_update_lvi(state, 0);
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ali_poll(struct file *file, struct poll_table_struct
-                            *wait)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned int mask = 0;
-       if (!dmabuf->ready)
-               return 0;
-       poll_wait(file, &dmabuf->wait, wait);
-       spin_lock_irqsave(&state->card->lock, flags);
-       ali_update_ptr(state);
-       if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) {
-               if (dmabuf->count >= (signed) dmabuf->fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE  && (dmabuf->enable & (DAC_RUNNING|CODEC_SPDIFOUT_RUNNING|CONTROLLER_SPDIFOUT_RUNNING))) {
-               if ((signed) dmabuf->dmasize >= dmabuf->count + (signed) dmabuf->fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&state->card->lock, flags);
-       return mask;
-}
-
-static int ali_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int ret = -EINVAL;
-       unsigned long size;
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-       }
-       if (vma->vm_flags & VM_READ) {
-               if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-       }
-       if ((ret = prog_dmabuf(state, 0)) != 0)
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << dmabuf->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       dmabuf->mapped = 1;
-       dmabuf->trigger = 0;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_channel *c = NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       unsigned int i_scr;
-       int val = 0, ret;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-#ifdef DEBUG
-       printk("ali_audio: ali_ioctl, arg=0x%x, cmd=",
-              arg ? *p : 0);
-#endif
-       switch (cmd) {
-       case OSS_GETVERSION:
-#ifdef DEBUG
-               printk("OSS_GETVERSION\n");
-#endif
-               return put_user(SOUND_VERSION, p);
-       case SNDCTL_DSP_RESET:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_RESET\n");
-#endif
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (dmabuf->enable == DAC_RUNNING) {
-                       c = dmabuf->write_channel;
-                       __stop_dac(state);
-               }
-               if (dmabuf->enable == ADC_RUNNING) {
-                       c = dmabuf->read_channel;
-                       __stop_adc(state);
-               }
-               if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-                       c = dmabuf->codec_spdifout_channel;
-                       __stop_spdifout(state);
-               }
-               if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-                       c = dmabuf->controller_spdifout_channel;
-                       __stop_spdifout(state);
-               }
-               if (c != NULL) {
-                       outb(2, state->card->iobase + c->port + OFF_CR);        /* reset DMA machine */
-                       outl(virt_to_bus(&c->sg[0]),
-                            state->card->iobase + c->port + OFF_BDBAR);
-                       outb(0, state->card->iobase + c->port + OFF_CIV);
-                       outb(0, state->card->iobase + c->port + OFF_LVI);
-               }
-
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               synchronize_irq(state->card->pci_dev->irq);
-               dmabuf->ready = 0;
-               dmabuf->swptr = dmabuf->hwptr = 0;
-               dmabuf->count = dmabuf->total_bytes = 0;
-               return 0;
-       case SNDCTL_DSP_SYNC:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SYNC\n");
-#endif
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->enable != CODEC_SPDIFOUT_RUNNING
-                           || file->f_flags & O_NONBLOCK)
-                               return 0;
-                       if ((val = drain_spdifout(state, 1)))
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->enable !=
-                                   CONTROLLER_SPDIFOUT_RUNNING
-                                   || file->f_flags & O_NONBLOCK)
-                                       return 0;
-                               if ((val = drain_spdifout(state, 1)))
-                                       return val;
-                       } else {
-                               if (dmabuf->enable != DAC_RUNNING
-                                   || file->f_flags & O_NONBLOCK)
-                                       return 0;
-                               if ((val = drain_dac(state, 1)))
-                                       return val;
-                       }
-               }
-               dmabuf->total_bytes = 0;
-               return 0;
-       case SNDCTL_DSP_SPEED:  /* set smaple rate */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SPEED\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               if ((state->card->ac97_status & SPDIF_ON)) {    /* S/PDIF Enabled */
-                                       /* RELTEK ALC650 only support 48000, need to check that */
-                                       if (ali_valid_spdif_rate(codec, val)) {
-                                               if (codec_independent_spdif_locked > 0) {
-                                                       ali_set_spdif_output(state, -1, 0);
-                                                       stop_spdifout(state);
-                                                       dmabuf->ready = 0;
-                                                       /* I add test codec independent spdif out */
-                                                       spin_lock_irqsave(&state->card->lock, flags);
-                                                       ali_set_codecspdifout_rate(state, val); // I modified
-                                                       spin_unlock_irqrestore(&state->card->lock, flags);
-                                                       /* Set S/PDIF transmitter rate. */
-                                                       i_scr = inl(state->card->iobase + ALI_SCR);
-                                                       if ((i_scr & 0x00300000) == 0x00100000) {
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                                       } else {
-                                                               if ((i_scr&0x00300000)  == 0x00200000)
-                                                               {
-                                                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                                                               } else {
-                                                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                                                       } else {
-                                                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                                                       }
-                                                               }
-                                                       }
-
-                                                       if (!(state->card->ac97_status & SPDIF_ON)) {
-                                                               val = dmabuf->rate;
-                                                       }
-                                               } else {
-                                                       if (controller_independent_spdif_locked > 0) 
-                                                       {
-                                                               stop_spdifout(state);
-                                                               dmabuf->ready = 0;
-                                                               spin_lock_irqsave(&state->card->lock, flags);
-                                                               ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-                                                               spin_unlock_irqrestore(&state->card->lock, flags);
-                                                       } else {
-                                                               /* Set DAC rate */
-                                                               ali_set_spdif_output(state, -1, 0);
-                                                               stop_dac(state);
-                                                               dmabuf->ready = 0;
-                                                               spin_lock_irqsave(&state->card->lock, flags);
-                                                               ali_set_dac_rate(state, val);
-                                                               spin_unlock_irqrestore(&state->card->lock, flags);
-                                                               /* Set S/PDIF transmitter rate. */
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_3_4, val);
-                                                               if (!(state->card->ac97_status & SPDIF_ON))
-                                                               {
-                                                                       val = dmabuf->rate;
-                                                               }
-                                                       }
-                                               }
-                                       } else {        /* Not a valid rate for S/PDIF, ignore it */
-                                               val = dmabuf->rate;
-                                       }
-                               } else {
-                                       stop_dac(state);
-                                       dmabuf->ready = 0;
-                                       spin_lock_irqsave(&state->card->lock, flags);
-                                       ali_set_dac_rate(state, val);
-                                       spin_unlock_irqrestore(&state->card->lock, flags);
-                               }
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(state);
-                               dmabuf->ready = 0;
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_set_adc_rate(state, val);
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       }
-               }
-               return put_user(dmabuf->rate, p);
-       case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_STEREO\n");
-#endif
-               if (dmabuf->enable & DAC_RUNNING) {
-                       stop_dac(state);
-               }
-               if (dmabuf->enable & ADC_RUNNING) {
-                       stop_adc(state);
-               }
-               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               return put_user(1, p);
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if (codec_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 2)))
-                                       return val;
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       if (!dmabuf->ready && (val = prog_dmabuf(state, 3)))
-                                               return val;
-                               } else {
-                                       if (!dmabuf->ready && (val = prog_dmabuf(state, 0)))
-                                               return val;
-                               }
-                       }
-               }
-
-               if (file->f_mode & FMODE_READ) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 1)))
-                               return val;
-               }
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
-#endif
-               return put_user(dmabuf->userfragsize, p);
-       case SNDCTL_DSP_GETFMTS:        /* Returns a mask of supported sample format */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETFMTS\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_SETFMT: /* Select sample format */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETFMT\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_CHANNELS:       // add support 4,6 channel 
-#ifdef DEBUG
-               printk("SNDCTL_DSP_CHANNELS\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val > 0) {
-                       if (dmabuf->enable & DAC_RUNNING) {
-                               stop_dac(state);
-                       }
-                       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                               stop_spdifout(state);
-                       }
-                       if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-                               stop_spdifout(state);
-                       }
-                       if (dmabuf->enable & ADC_RUNNING) {
-                               stop_adc(state);
-                       }
-               } else {
-                       return put_user(state->card->channels, p);
-               }
-
-               i_scr = inl(state->card->iobase + ALI_SCR);
-               /* Current # of channels enabled */
-               if (i_scr & 0x00000100)
-                       ret = 4;
-               else if (i_scr & 0x00000200)
-                       ret = 6;
-               else
-                       ret = 2;
-               switch (val) {
-               case 2: /* 2 channels is always supported */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00100000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl((i_scr & 0xfffffcff), (state->card->iobase + ALI_SCR));
-                       /* Do we need to change mixer settings????  */
-                       break;
-               case 4: /* Supported on some chipsets, better check first */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00000100 | 0x00200000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl(((i_scr & 0xfffffcff) | 0x00000100), (state->card->iobase + ALI_SCR));
-                       break;
-               case 6: /* Supported on some chipsets, better check first */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000 | 0x00300000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000), (state->card->iobase + ALI_SCR));
-                       break;
-               default:        /* nothing else is ever supported by the chipset */
-                       val = ret;
-                       break;
-               }
-               return put_user(val, p);
-       case SNDCTL_DSP_POST:   /* the user has sent all data and is notifying us */
-               /* we update the swptr to the end of the last sg segment then return */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_POST\n");
-#endif
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready || (dmabuf->enable != CODEC_SPDIFOUT_RUNNING))
-                               return 0;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready || (dmabuf->enable != CONTROLLER_SPDIFOUT_RUNNING))
-                                       return 0;
-                       } else {
-                               if (!dmabuf->ready || (dmabuf->enable != DAC_RUNNING))
-                                       return 0;
-                       }
-               }
-               if ((dmabuf->swptr % dmabuf->fragsize) != 0) {
-                       val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize);
-                       dmabuf->swptr += val;
-                       dmabuf->count += val;
-               }
-               return 0;
-       case SNDCTL_DSP_SUBDIVIDE:
-               if (dmabuf->subdivision)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SUBDIVIDE %d\n", val);
-#endif
-               dmabuf->subdivision = val;
-               dmabuf->ready = 0;
-               return 0;
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               dmabuf->ossfragsize = 1 << (val & 0xffff);
-               dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-               if (!dmabuf->ossfragsize || !dmabuf->ossmaxfrags)
-                       return -EINVAL;
-               /*
-                * Bound the frag size into our allowed range of 256 - 4096
-                */
-               if (dmabuf->ossfragsize < 256)
-                       dmabuf->ossfragsize = 256;
-               else if (dmabuf->ossfragsize > 4096)
-                       dmabuf->ossfragsize = 4096;
-               /*
-                * The numfrags could be something reasonable, or it could
-                * be 0xffff meaning "Give me as much as possible".  So,
-                * we check the numfrags * fragsize doesn't exceed our
-                * 64k buffer limit, nor is it less than our 8k minimum.
-                * If it fails either one of these checks, then adjust the
-                * number of fragments, not the size of them.  It's OK if
-                * our number of fragments doesn't equal 32 or anything
-                * like our hardware based number now since we are using
-                * a different frag count for the hardware.  Before we get
-                * into this though, bound the maxfrags to avoid overflow
-                * issues.  A reasonable bound would be 64k / 256 since our
-                * maximum buffer size is 64k and our minimum frag size is
-                * 256.  On the other end, our minimum buffer size is 8k and
-                * our maximum frag size is 4k, so the lower bound should
-                * be 2.
-                */
-               if (dmabuf->ossmaxfrags > 256)
-                       dmabuf->ossmaxfrags = 256;
-               else if (dmabuf->ossmaxfrags < 2)
-                       dmabuf->ossmaxfrags = 2;
-               val = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-               while (val < 8192) {
-                       val <<= 1;
-                       dmabuf->ossmaxfrags <<= 1;
-               }
-               while (val > 65536) {
-                       val >>= 1;
-                       dmabuf->ossmaxfrags >>= 1;
-               }
-               dmabuf->ready = 0;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val,
-                      dmabuf->ossfragsize, dmabuf->ossmaxfrags);
-#endif
-               return 0;
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-                                       return val;
-                       } else {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                                       return val;
-                       }
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               abinfo.fragsize = dmabuf->userfragsize;
-               abinfo.fragstotal = dmabuf->userfrags;
-               if (dmabuf->mapped)
-                       abinfo.bytes = dmabuf->dmasize;
-               else
-                       abinfo.bytes = ali_get_free_write_space(state);
-               abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n",
-                      abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-                      abinfo.fragstotal);
-#endif
-               return copy_to_user(argp, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-                                       return val;
-                       } else {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                                       return val;
-                       }
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               val = ali_get_free_write_space(state);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.ptr = dmabuf->hwptr;
-               cinfo.blocks = val / dmabuf->userfragsize;
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                               dmabuf->count += val;
-                               dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 2);
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                                       dmabuf->count += val;
-                                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                                       __ali_update_lvi(state, 3);
-                               }
-                       } else {
-                               if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-                                       dmabuf->count += val;
-                                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                                       __ali_update_lvi(state, 0);
-                               }
-                       }
-               }
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
-                      cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0;
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->card->lock, flags);
-               abinfo.bytes = ali_get_available_read_data(state);
-               abinfo.fragsize = dmabuf->userfragsize;
-               abinfo.fragstotal = dmabuf->userfrags;
-               abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n",
-                      abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-                      abinfo.fragstotal);
-#endif
-               return copy_to_user(argp, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->card->lock, flags);
-               val = ali_get_available_read_data(state);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = val / dmabuf->userfragsize;
-               cinfo.ptr = dmabuf->hwptr;
-               if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-                       dmabuf->count -= val;
-                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                       __ali_update_lvi(state, 1);
-               }
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
-                      cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0;
-       case SNDCTL_DSP_NONBLOCK:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_NONBLOCK\n");
-#endif
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-       case SNDCTL_DSP_GETCAPS:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETCAPS\n");
-#endif
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
-                               DSP_CAP_MMAP | DSP_CAP_BIND, p);
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
-#endif
-               return put_user(dmabuf->trigger, p);
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
-#endif
-               if (!(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
-                       stop_adc(state);
-               }
-               if (!(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
-                       stop_dac(state);
-               }
-               if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               dmabuf->trigger = val;
-               if (val & PCM_ENABLE_OUTPUT && !(dmabuf->enable & DAC_RUNNING)) {
-                       if (!dmabuf->write_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
-                               if (!dmabuf->write_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 0);
-                               spin_unlock_irqrestore(&state->card->lock,
-                                                      flags);
-                       } else
-                               start_dac(state);
-               }
-               if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CODEC_SPDIFOUT_RUNNING)) {
-                       if (!dmabuf->codec_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->codec_spdifout_channel = state->card->alloc_codec_spdifout_channel(state->card);
-                               if (!dmabuf->codec_spdifout_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 2);
-                               spin_unlock_irqrestore(&state->card->lock,
-                                                      flags);
-                       } else
-                               start_spdifout(state);
-               }
-               if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)) {
-                       if (!dmabuf->controller_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->controller_spdifout_channel = state->card->alloc_controller_spdifout_channel(state->card);
-                               if (!dmabuf->controller_spdifout_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 3);
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       } else
-                               start_spdifout(state);
-               }
-               if (val & PCM_ENABLE_INPUT && !(dmabuf->enable & ADC_RUNNING)) {
-                       if (!dmabuf->read_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
-                               if (!dmabuf->read_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock,
-                                                 flags);
-                               ali_update_ptr(state);
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = 0;
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       }
-                       ali_update_lvi(state, 1);
-                       start_adc(state);
-               }
-               return 0;
-       case SNDCTL_DSP_SETDUPLEX:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETDUPLEX\n");
-#endif
-               return -EINVAL;
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               val = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
-#endif
-               return put_user(val, p);
-       case SOUND_PCM_READ_RATE:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
-#endif
-               return put_user(dmabuf->rate, p);
-       case SOUND_PCM_READ_CHANNELS:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_CHANNELS\n");
-#endif
-               return put_user(2, p);
-       case SOUND_PCM_READ_BITS:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_BITS\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_SETSPDIF:       /* Set S/PDIF Control register */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETSPDIF\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Check to make sure the codec supports S/PDIF transmitter */
-               if ((state->card->ac97_features & 4)) {
-                       /* mask out the transmitter speed bits so the user can't set them */
-                       val &= ~0x3000;
-                       /* Add the current transmitter speed bits to the passed value */
-                       ret = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-                       val |= (ret & 0x3000);
-                       ali_ac97_set(codec, AC97_SPDIF_CONTROL, val);
-                       if (ali_ac97_get(codec, AC97_SPDIF_CONTROL) != val) {
-                               printk(KERN_ERR "ali_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val);
-                               return -EFAULT;
-                       }
-               }
-#ifdef DEBUG
-               else
-                       printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-               return put_user(val, p);
-       case SNDCTL_DSP_GETSPDIF:       /* Get S/PDIF Control register */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETSPDIF\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Check to make sure the codec supports S/PDIF transmitter */
-               if (!(state->card->ac97_features & 4)) {
-#ifdef DEBUG
-                       printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-                       val = 0;
-               } else {
-                       val = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-               }
-
-               return put_user(val, p);
-//end add support spdif out
-//add support 4,6 channel
-       case SNDCTL_DSP_GETCHANNELMASK:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETCHANNELMASK\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Based on AC'97 DAC support, not ICH hardware */
-               val = DSP_BIND_FRONT;
-               if (state->card->ac97_features & 0x0004)
-                       val |= DSP_BIND_SPDIF;
-               if (state->card->ac97_features & 0x0080)
-                       val |= DSP_BIND_SURR;
-               if (state->card->ac97_features & 0x0140)
-                       val |= DSP_BIND_CENTER_LFE;
-               return put_user(val, p);
-       case SNDCTL_DSP_BIND_CHANNEL:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_BIND_CHANNEL\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val == DSP_BIND_QUERY) {
-                       val = DSP_BIND_FRONT;   /* Always report this as being enabled */
-                       if (state->card->ac97_status & SPDIF_ON)
-                               val |= DSP_BIND_SPDIF;
-                       else {
-                               if (state->card->ac97_status & SURR_ON)
-                                       val |= DSP_BIND_SURR;
-                               if (state->card->
-                                   ac97_status & CENTER_LFE_ON)
-                                       val |= DSP_BIND_CENTER_LFE;
-                       }
-               } else {        /* Not a query, set it */
-                       if (!(file->f_mode & FMODE_WRITE))
-                               return -EINVAL;
-                       if (dmabuf->enable == DAC_RUNNING) {
-                               stop_dac(state);
-                       }
-                       if (val & DSP_BIND_SPDIF) {     /* Turn on SPDIF */
-                               /*  Ok, this should probably define what slots
-                                *  to use. For now, we'll only set it to the
-                                *  defaults:
-                                * 
-                                *   non multichannel codec maps to slots 3&4
-                                *   2 channel codec maps to slots 7&8
-                                *   4 channel codec maps to slots 6&9
-                                *   6 channel codec maps to slots 10&11
-                                *
-                                *  there should be some way for the app to
-                                *  select the slot assignment.
-                                */
-                               i_scr = inl(state->card->iobase + ALI_SCR);
-                               if (codec_independent_spdif_locked > 0) {
-
-                                       if ((i_scr & 0x00300000) == 0x00100000) {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                       } else {
-                                               if ((i_scr & 0x00300000) == 0x00200000) {
-                                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                                               } else {
-                                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                                       }
-                                               }
-                                       }
-                               } else {        /* codec spdif out (pcm out share ) */
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_3_4, dmabuf->rate);    //I do not modify
-                               }
-
-                               if (!(state->card->ac97_status & SPDIF_ON))
-                                       val &= ~DSP_BIND_SPDIF;
-                       } else {
-                               int mask;
-                               int channels;
-                               /* Turn off S/PDIF if it was on */
-                               if (state->card->ac97_status & SPDIF_ON)
-                                       ali_set_spdif_output(state, -1, 0);
-                               mask =
-                                   val & (DSP_BIND_FRONT | DSP_BIND_SURR |
-                                          DSP_BIND_CENTER_LFE);
-                               switch (mask) {
-                               case DSP_BIND_FRONT:
-                                       channels = 2;
-                                       break;
-                               case DSP_BIND_FRONT | DSP_BIND_SURR:
-                                       channels = 4;
-                                       break;
-                               case DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE:
-                                       channels = 6;
-                                       break;
-                               default:
-                                       val = DSP_BIND_FRONT;
-                                       channels = 2;
-                                       break;
-                               }
-                               ali_set_dac_channels(state, channels);
-                               /* check that they really got turned on */
-                               if (!state->card->ac97_status & SURR_ON)
-                                       val &= ~DSP_BIND_SURR;
-                               if (!state->card->
-                                   ac97_status & CENTER_LFE_ON)
-                                       val &= ~DSP_BIND_CENTER_LFE;
-                       }
-               }
-               return put_user(val, p);
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_WRITE_FILTER:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-       return -EINVAL;
-}
-
-static int ali_open(struct inode *inode, struct file *file)
-{
-       int i = 0;
-       struct ali_card *card = devs;
-       struct ali_state *state = NULL;
-       struct dmabuf *dmabuf = NULL;
-       unsigned int i_scr;
-       
-       /* find an available virtual channel (instance of /dev/dsp) */
-       
-       while (card != NULL) {
-
-               /*
-                * If we are initializing and then fail, card could go
-                * away unuexpectedly while we are in the for() loop.
-                * So, check for card on each iteration before we check
-                * for card->initializing to avoid a possible oops.
-                * This usually only matters for times when the driver is
-                * autoloaded by kmod.
-                */
-               for (i = 0; i < 50 && card && card->initializing; i++) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ / 20);
-               }
-
-               for (i = 0; i < NR_HW_CH && card && !card->initializing; i++) {
-                       if (card->states[i] == NULL) {
-                               state = card->states[i] = (struct ali_state *) kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-                               if (state == NULL)
-                                       return -ENOMEM;
-                               memset(state, 0, sizeof(struct ali_state));
-                               dmabuf = &state->dmabuf;
-                               goto found_virt;
-                       }
-               }
-               card = card->next;
-       }
-
-       /* no more virtual channel avaiable */
-       if (!state)
-               return -ENODEV;
-found_virt:
-       /* initialize the virtual channel */
-
-       state->virt = i;
-       state->card = card;
-       state->magic = ALI5455_STATE_MAGIC;
-       init_waitqueue_head(&dmabuf->wait);
-       mutex_init(&state->open_mutex);
-       file->private_data = state;
-       dmabuf->trigger = 0;
-       /* allocate hardware channels */
-       if (file->f_mode & FMODE_READ) {
-               if ((dmabuf->read_channel =
-                    card->alloc_rec_pcm_channel(card)) == NULL) {
-                       kfree(card->states[i]);
-                       card->states[i] = NULL;
-                       return -EBUSY;
-               }
-               dmabuf->trigger |= PCM_ENABLE_INPUT;
-               ali_set_adc_rate(state, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (codec_independent_spdif_locked > 0) {
-                       if ((dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card)) == NULL) {
-                               kfree(card->states[i]);
-                               card->states[i] = NULL;
-                               return -EBUSY;
-                       }
-                       dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-                       ali_set_codecspdifout_rate(state, codec_independent_spdif_locked);      //It must add
-                       i_scr = inl(state->card->iobase + ALI_SCR);
-                       if ((i_scr & 0x00300000) == 0x00100000) {
-                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                       } else {
-                               if ((i_scr & 0x00300000) == 0x00200000) {
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                               } else {
-                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                       } else {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                       }
-                               }
-
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if ((dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card)) == NULL) {
-                                       kfree(card->states[i]);
-                                       card->states[i] = NULL;
-                                       return -EBUSY;
-                               }
-                               dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-                               ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-                       } else {
-                               if ((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) {
-                                       kfree(card->states[i]);
-                                       card->states[i] = NULL;
-                                       return -EBUSY;
-                               }
-                               /* Initialize to 8kHz?  What if we don't support 8kHz? */
-                               /*  Let's change this to check for S/PDIF stuff */
-
-                               dmabuf->trigger |= PCM_ENABLE_OUTPUT;
-                               if (codec_pcmout_share_spdif_locked) {
-                                       ali_set_dac_rate(state, codec_pcmout_share_spdif_locked);
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_3_4, codec_pcmout_share_spdif_locked);
-                               } else {
-                                       ali_set_dac_rate(state, 8000);
-                               }
-                       }
-
-               }
-       }
-
-       /* set default sample format. According to OSS Programmer's Guide  /dev/dsp
-          should be default to unsigned 8-bits, mono, with sample rate 8kHz and
-          /dev/dspW will accept 16-bits sample, but we don't support those so we
-          set it immediately to stereo and 16bit, which is all we do support */
-       dmabuf->fmt |= ALI5455_FMT_16BIT | ALI5455_FMT_STEREO;
-       dmabuf->ossfragsize = 0;
-       dmabuf->ossmaxfrags = 0;
-       dmabuf->subdivision = 0;
-       state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-       return nonseekable_open(inode, file);
-}
-
-static int ali_release(struct inode *inode, struct file *file)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state->card;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       lock_kernel();
-       
-       /* stop DMA state machine and free DMA buffers/channels */
-       if (dmabuf->trigger & PCM_ENABLE_OUTPUT)
-               drain_dac(state, 0);
-
-       if (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)
-               drain_spdifout(state, 0);
-       
-       if (dmabuf->trigger & PCM_ENABLE_INPUT)
-               stop_adc(state);
-       
-       spin_lock_irqsave(&card->lock, flags);
-       dealloc_dmabuf(state);
-       if (file->f_mode & FMODE_WRITE) {
-               if (codec_independent_spdif_locked > 0) {
-                       state->card->free_pcm_channel(state->card, dmabuf->codec_spdifout_channel->num);
-               } else {
-                       if (controller_independent_spdif_locked > 0)
-                               state->card->free_pcm_channel(state->card,
-                                                             dmabuf->controller_spdifout_channel->num);
-                       else state->card->free_pcm_channel(state->card,
-                                                             dmabuf->write_channel->num);
-               }
-       }
-       if (file->f_mode & FMODE_READ)
-               state->card->free_pcm_channel(state->card, dmabuf->read_channel->num);
-
-       state->card->states[state->virt] = NULL;
-       kfree(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const */ struct file_operations ali_audio_fops = {
-       .owner          = THIS_MODULE, 
-       .llseek         = no_llseek, 
-       .read           = ali_read,
-       .write          = ali_write, 
-       .poll           = ali_poll,
-       .ioctl          = ali_ioctl,
-       .mmap           = ali_mmap,
-       .open           = ali_open,
-       .release        = ali_release,
-};
-
-/* Read AC97 codec registers */
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg)
-{
-       struct ali_card *card = dev->private_data;
-       int count1 = 100;
-       char val;
-       unsigned short int data = 0, count, addr1, addr2 = 0;
-
-       spin_lock(&card->ac97_lock);
-       while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-               udelay(1);
-
-       addr1 = reg;
-       reg |= 0x0080;
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x08)
-                       break;
-       }
-       if (count == 0x7f)
-       {
-               spin_unlock(&card->ac97_lock);
-               return -1;
-       }
-       outw(reg, (card->iobase + ALI_CPR) + 2);
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x02) {
-                       data = inw(card->iobase + ALI_SPR);
-                       addr2 = inw((card->iobase + ALI_SPR) + 2);
-                       break;
-               }
-       }
-       spin_unlock(&card->ac97_lock);
-       if (count == 0x7f)
-               return -1;
-       if (addr2 != addr1)
-               return -1;
-       return ((u16) data);
-}
-
-/* write ac97 codec register   */
-
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
-{
-       struct ali_card *card = dev->private_data;
-       int count1 = 100;
-       char val;
-       unsigned short int count;
-
-       spin_lock(&card->ac97_lock);
-       while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-               udelay(1);
-
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x08)
-                       break;
-       }
-       if (count == 0x7f) {
-               printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-               spin_unlock(&card->ac97_lock);
-               return;
-       }
-       outw(data, (card->iobase + ALI_CPR));
-       outb(reg, (card->iobase + ALI_CPR) + 2);
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x01)
-                       break;
-       }
-       spin_unlock(&card->ac97_lock);
-       if (count == 0x7f)
-               printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-       return;
-}
-
-/* OSS /dev/mixer file operation methods */
-
-static int ali_open_mixdev(struct inode *inode, struct file *file)
-{
-       int i;
-       int minor = iminor(inode);
-       struct ali_card *card = devs;
-       for (card = devs; card != NULL; card = card->next) {
-               /*
-                * If we are initializing and then fail, card could go
-                * away unuexpectedly while we are in the for() loop.
-                * So, check for card on each iteration before we check
-                * for card->initializing to avoid a possible oops.
-                * This usually only matters for times when the driver is
-                * autoloaded by kmod.
-                */
-               for (i = 0; i < 50 && card && card->initializing; i++) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ / 20);
-               }
-               for (i = 0; i < NR_AC97 && card && !card->initializing; i++)
-                       if (card->ac97_codec[i] != NULL
-                           && card->ac97_codec[i]->dev_mixer == minor) {
-                               file->private_data = card->ac97_codec[i];
-                               return nonseekable_open(inode, file);
-                       }
-       }
-       return -ENODEV;
-}
-
-static int ali_ioctl_mixdev(struct inode *inode,
-                           struct file *file,
-                           unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations ali_mixer_fops = {
-       .owner  = THIS_MODULE, 
-       .llseek = no_llseek, 
-       .ioctl  = ali_ioctl_mixdev,
-       .open   = ali_open_mixdev,
-};
-
-/* AC97 codec initialisation.  These small functions exist so we don't
-   duplicate code between module init and apm resume */
-
-static inline int ali_ac97_exists(struct ali_card *card, int ac97_number)
-{
-       unsigned int i = 1;
-       u32 reg = inl(card->iobase + ALI_RTSR);
-       if (ac97_number) {
-               while (i < 100) {
-
-                       reg = inl(card->iobase + ALI_RTSR);
-                       if (reg & 0x40) {
-                               break;
-                       } else {
-                               outl(reg | 0x00000040,
-                                    card->iobase + 0x34);
-                               udelay(1);
-                       }
-                       i++;
-               }
-
-       } else {
-               while (i < 100) {
-                       reg = inl(card->iobase + ALI_RTSR);
-                       if (reg & 0x80) {
-                               break;
-                       } else {
-                               outl(reg | 0x00000080,
-                                    card->iobase + 0x34);
-                               udelay(1);
-                       }
-                       i++;
-               }
-       }
-
-       if (ac97_number)
-               return reg & 0x40;
-       else
-               return reg & 0x80;
-}
-
-static inline int ali_ac97_enable_variable_rate(struct ac97_codec *codec)
-{
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, ali_ac97_get(codec, AC97_EXTENDED_STATUS) | 0xE800);
-       return (ali_ac97_get(codec, AC97_EXTENDED_STATUS) & 1);
-}
-
-
-static int ali_ac97_probe_and_powerup(struct ali_card *card, struct ac97_codec *codec)
-{
-       /* Returns 0 on failure */
-       int i;
-       u16 addr;
-       if (ac97_probe_codec(codec) == 0)
-               return 0;
-       /* ac97_probe_codec is success ,then begin to init codec */
-       ali_ac97_set(codec, AC97_RESET, 0xffff);
-       if (card->channel[0].used == 1) {
-               ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-               ali_ac97_set(codec, AC97_LINEIN_VOL, 0x0808);
-               ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-       }
-
-       if (card->channel[2].used == 1) //if MICin then init codec
-       {
-               ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-               ali_ac97_set(codec, AC97_MIC_VOL, 0x8808);
-               ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-               ali_ac97_set(codec, AC97_RECORD_GAIN_MIC, 0x0000);
-       }
-
-       ali_ac97_set(codec, AC97_MASTER_VOL_STEREO, 0x0000);
-       ali_ac97_set(codec, AC97_HEADPHONE_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_PCMOUT_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_CD_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_VIDEO_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_AUX_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_PHONE_VOL, 0x8048);
-       ali_ac97_set(codec, AC97_PCBEEP_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_GENERAL_PURPOSE, AC97_GP_MIX);
-       ali_ac97_set(codec, AC97_MASTER_VOL_MONO, 0x0000);
-       ali_ac97_set(codec, 0x38, 0x0000);
-       addr = ali_ac97_get(codec, 0x2a);
-       ali_ac97_set(codec, 0x2a, addr | 0x0001);
-       addr = ali_ac97_get(codec, 0x2a);
-       addr = ali_ac97_get(codec, 0x28);
-       ali_ac97_set(codec, 0x2c, 0xbb80);
-       addr = ali_ac97_get(codec, 0x2c);
-       /* power it all up */
-       ali_ac97_set(codec, AC97_POWER_CONTROL,
-                    ali_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
-       /* wait for analog ready */
-       for (i = 10; i && ((ali_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(HZ / 20);
-       }
-       /* FIXME !! */
-       i++;
-       return i;
-}
-
-
-/* I clone ali5455(2.4.7 )  not clone i810_audio(2.4.18)  */
-
-static int ali_reset_5455(struct ali_card *card)
-{
-       outl(0x80000003, card->iobase + ALI_SCR);
-       outl(0x83838383, card->iobase + ALI_FIFOCR1);
-       outl(0x83838383, card->iobase + ALI_FIFOCR2);
-       if (controller_pcmout_share_spdif_locked > 0) {
-               outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-                    card->iobase + ALI_SPDIFICS);
-               outl(0x0408000a, card->iobase + ALI_INTERFACECR);
-       } else {
-               if (codec_independent_spdif_locked > 0) {
-                       outl((inl(card->iobase + ALI_SCR) | 0x00100000), card->iobase + ALI_SCR);       // now I select slot 7 & 8
-                       outl(0x00200000, card->iobase + ALI_INTERFACECR);       //enable codec independent spdifout 
-               } else
-                       outl(0x04080002, card->iobase + ALI_INTERFACECR);
-       }
-
-       outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-       if (controller_independent_spdif_locked > 0)
-               outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-                    card->iobase + ALI_SPDIFICS);
-       return 1;
-}
-
-
-static int ali_ac97_random_init_stuff(struct ali_card
-                                     *card)
-{
-       u32 reg = inl(card->iobase + ALI_SCR);
-       int i = 0;
-       reg = inl(card->iobase + ALI_SCR);
-       if ((reg & 2) == 0)     /* Cold required */
-               reg |= 2;
-       else
-               reg |= 1;       /* Warm */
-       reg &= ~0x80000000;     /* ACLink on */
-       outl(reg, card->iobase + ALI_SCR);
-
-       while (i < 10) {
-               if ((inl(card->iobase + 0x18) & (1 << 1)) == 0)
-                       break;
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout(HZ / 20);
-               i++;
-       }
-       if (i == 10) {
-               printk(KERN_ERR "ali_audio: AC'97 reset failed.\n");
-               return 0;
-       }
-
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 2);
-       return 1;
-}
-
-/* AC97 codec initialisation. */
-
-static int __devinit ali_ac97_init(struct ali_card *card)
-{
-       int num_ac97 = 0;
-       int total_channels = 0;
-       struct ac97_codec *codec;
-       u16 eid;
-
-       if (!ali_ac97_random_init_stuff(card))
-               return 0;
-
-       /* Number of channels supported */
-       /* What about the codec?  Just because the ICH supports */
-       /* multiple channels doesn't mean the codec does.       */
-       /* we'll have to modify this in the codec section below */
-       /* to reflect what the codec has.                       */
-       /* ICH and ICH0 only support 2 channels so don't bother */
-       /* to check....                                         */
-       inl(card->iobase + ALI_CPR);
-       card->channels = 2;
-
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-
-               /* Assume codec isn't available until we go through the
-                * gauntlet below */
-               card->ac97_codec[num_ac97] = NULL;
-               /* The ICH programmer's reference says you should   */
-               /* check the ready status before probing. So we chk */
-               /*   What do we do if it's not ready?  Wait and try */
-               /*   again, or abort?                               */
-               if (!ali_ac97_exists(card, num_ac97)) {
-                       if (num_ac97 == 0)
-                               printk(KERN_ERR "ali_audio: Primary codec not ready.\n");
-                       break;
-               }
-
-               if ((codec = ac97_alloc_codec()) == NULL)
-                       return -ENOMEM;
-               /* initialize some basic codec information, other fields will be filled
-                  in ac97_probe_codec */
-               codec->private_data = card;
-               codec->id = num_ac97;
-               codec->codec_read = ali_ac97_get;
-               codec->codec_write = ali_ac97_set;
-               if (!ali_ac97_probe_and_powerup(card, codec)) {
-                       printk(KERN_ERR "ali_audio: timed out waiting for codec %d analog ready",
-                            num_ac97);
-                       kfree(codec);
-                       break;  /* it didn't work */
-               }
-               
-               /* Store state information about S/PDIF transmitter */
-               card->ac97_status = 0;
-               /* Don't attempt to get eid until powerup is complete */
-               eid = ali_ac97_get(codec, AC97_EXTENDED_ID);
-               if (eid == 0xFFFF) {
-                       printk(KERN_ERR "ali_audio: no codec attached ?\n");
-                       kfree(codec);
-                       break;
-               }
-
-               card->ac97_features = eid;
-               /* Now check the codec for useful features to make up for
-                  the dumbness of the ali5455 hardware engine */
-               if (!(eid & 0x0001))
-                       printk(KERN_WARNING
-                              "ali_audio: only 48Khz playback available.\n");
-               else {
-                       if (!ali_ac97_enable_variable_rate(codec)) {
-                               printk(KERN_WARNING
-                                      "ali_audio: Codec refused to allow VRA, using 48Khz only.\n");
-                               card->ac97_features &= ~1;
-                       }
-               }
-
-               /* Determine how many channels the codec(s) support   */
-               /*   - The primary codec always supports 2            */
-               /*   - If the codec supports AMAP, surround DACs will */
-               /*     automaticlly get assigned to slots.            */
-               /*     * Check for surround DACs and increment if     */
-               /*       found.                                       */
-               /*   - Else check if the codec is revision 2.2        */
-               /*     * If surround DACs exist, assign them to slots */
-               /*       and increment channel count.                 */
-
-               /* All of this only applies to ICH2 and above. ICH    */
-               /* and ICH0 only support 2 channels.  ICH2 will only  */
-               /* support multiple codecs in a "split audio" config. */
-               /* as described above.                                */
-
-               /* TODO: Remove all the debugging messages!           */
-
-               if ((eid & 0xc000) == 0)        /* primary codec */
-                       total_channels += 2;
-               if ((codec->dev_mixer = register_sound_mixer(&ali_mixer_fops, -1)) < 0) {
-                       printk(KERN_ERR "ali_audio: couldn't register mixer!\n");
-                       kfree(codec);
-                       break;
-               }
-               card->ac97_codec[num_ac97] = codec;
-       }
-       /* pick the minimum of channels supported by ICHx or codec(s) */
-       card->channels = (card->channels > total_channels) ? total_channels : card->channels;
-       return num_ac97;
-}
-
-static void __devinit ali_configure_clocking(void)
-{
-       struct ali_card *card;
-       struct ali_state *state;
-       struct dmabuf *dmabuf;
-       unsigned int i, offset, new_offset;
-       unsigned long flags;
-       card = devs;
-
-       /* We could try to set the clocking for multiple cards, but can you even have
-        * more than one ali in a machine?  Besides, clocking is global, so unless
-        * someone actually thinks more than one ali in a machine is possible and
-        * decides to rewrite that little bit, setting the rate for more than one card
-        * is a waste of time.
-        */
-       if (card != NULL) {
-               state = card->states[0] = (struct ali_state *)
-                   kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-               if (state == NULL)
-                       return;
-               memset(state, 0, sizeof(struct ali_state));
-               dmabuf = &state->dmabuf;
-               dmabuf->write_channel = card->alloc_pcm_channel(card);
-               state->virt = 0;
-               state->card = card;
-               state->magic = ALI5455_STATE_MAGIC;
-               init_waitqueue_head(&dmabuf->wait);
-               mutex_init(&state->open_mutex);
-               dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT;
-               dmabuf->trigger = PCM_ENABLE_OUTPUT;
-               ali_set_dac_rate(state, 48000);
-               if (prog_dmabuf(state, 0) != 0)
-                       goto config_out_nodmabuf;
-               
-               if (dmabuf->dmasize < 16384)
-                       goto config_out;
-               
-               dmabuf->count = dmabuf->dmasize;
-               outb(31, card->iobase + dmabuf->write_channel->port + OFF_LVI);
-
-               local_irq_save(flags);
-               start_dac(state);
-               offset = ali_get_dma_addr(state, 0);
-               mdelay(50);
-               new_offset = ali_get_dma_addr(state, 0);
-               stop_dac(state);
-               
-               outb(2, card->iobase + dmabuf->write_channel->port + OFF_CR);
-               local_irq_restore(flags);
-
-               i = new_offset - offset;
-
-               if (i == 0)
-                       goto config_out;
-               i = i / 4 * 20;
-               if (i > 48500 || i < 47500) {
-                       clocking = clocking * clocking / i;
-               }
-config_out:
-               dealloc_dmabuf(state);
-config_out_nodmabuf:
-               state->card->free_pcm_channel(state->card, state->dmabuf. write_channel->num);
-               kfree(state);
-               card->states[0] = NULL;
-       }
-}
-
-/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
-   until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
-
-static int __devinit ali_probe(struct pci_dev *pci_dev,
-                              const struct pci_device_id *pci_id)
-{
-       struct ali_card *card;
-       if (pci_enable_device(pci_dev))
-               return -EIO;
-       if (pci_set_dma_mask(pci_dev, ALI5455_DMA_MASK)) {
-               printk(KERN_ERR "ali5455: architecture does not support"
-                      " 32bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-
-       if ((card = kmalloc(sizeof(struct ali_card), GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "ali_audio: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(card, 0, sizeof(*card));
-       card->initializing = 1;
-       card->iobase = pci_resource_start(pci_dev, 0);
-       card->pci_dev = pci_dev;
-       card->pci_id = pci_id->device;
-       card->irq = pci_dev->irq;
-       card->next = devs;
-       card->magic = ALI5455_CARD_MAGIC;
-#ifdef CONFIG_PM
-       card->pm_suspended = 0;
-#endif
-       spin_lock_init(&card->lock);
-       spin_lock_init(&card->ac97_lock);
-       devs = card;
-       pci_set_master(pci_dev);
-       printk(KERN_INFO "ali: %s found at IO 0x%04lx, IRQ %d\n",
-              card_names[pci_id->driver_data], card->iobase, card->irq);
-       card->alloc_pcm_channel = ali_alloc_pcm_channel;
-       card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel;
-       card->alloc_rec_mic_channel = ali_alloc_rec_mic_channel;
-       card->alloc_codec_spdifout_channel = ali_alloc_codec_spdifout_channel;
-       card->alloc_controller_spdifout_channel = ali_alloc_controller_spdifout_channel;
-       card->free_pcm_channel = ali_free_pcm_channel;
-       card->channel[0].offset = 0;
-       card->channel[0].port = 0x40;
-       card->channel[0].num = 0;
-       card->channel[1].offset = 0;
-       card->channel[1].port = 0x50;
-       card->channel[1].num = 1;
-       card->channel[2].offset = 0;
-       card->channel[2].port = 0x60;
-       card->channel[2].num = 2;
-       card->channel[3].offset = 0;
-       card->channel[3].port = 0x70;
-       card->channel[3].num = 3;
-       card->channel[4].offset = 0;
-       card->channel[4].port = 0xb0;
-       card->channel[4].num = 4;
-       /* claim our iospace and irq */
-       request_region(card->iobase, 256, card_names[pci_id->driver_data]);
-       if (request_irq(card->irq, &ali_interrupt, IRQF_SHARED,
-                       card_names[pci_id->driver_data], card)) {
-               printk(KERN_ERR "ali_audio: unable to allocate irq %d\n",
-                      card->irq);
-               release_region(card->iobase, 256);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       if (ali_reset_5455(card) <= 0) {
-               unregister_sound_dsp(card->dev_audio);
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       /* initialize AC97 codec and register /dev/mixer */
-       if (ali_ac97_init(card) < 0) {
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
-       }
-       
-       pci_set_drvdata(pci_dev, card);
-       
-       if (clocking == 0) {
-               clocking = 48000;
-               ali_configure_clocking();
-       }
-
-       /* register /dev/dsp */
-       if ((card->dev_audio = register_sound_dsp(&ali_audio_fops, -1)) < 0) {
-               int i;
-               printk(KERN_ERR"ali_audio: couldn't register DSP device!\n");
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               for (i = 0; i < NR_AC97; i++)
-                       if (card->ac97_codec[i] != NULL) {
-                               unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-                               kfree(card->ac97_codec[i]);
-                       }
-               kfree(card);
-               return -ENODEV;
-       }
-       card->initializing = 0;
-       return 0;
-}
-
-static void __devexit ali_remove(struct pci_dev *pci_dev)
-{
-       int i;
-       struct ali_card *card = pci_get_drvdata(pci_dev);
-       /* free hardware resources */
-       free_irq(card->irq, devs);
-       release_region(card->iobase, 256);
-       /* unregister audio devices */
-       for (i = 0; i < NR_AC97; i++)
-               if (card->ac97_codec[i] != NULL) {
-                       unregister_sound_mixer(card->ac97_codec[i]->
-                                              dev_mixer);
-                       ac97_release_codec(card->ac97_codec[i]);
-                       card->ac97_codec[i] = NULL;
-               }
-       unregister_sound_dsp(card->dev_audio);
-       kfree(card);
-}
-
-#ifdef CONFIG_PM
-static int ali_pm_suspend(struct pci_dev *dev, pm_message_t pm_state)
-{
-       struct ali_card *card = pci_get_drvdata(dev);
-       struct ali_state *state;
-       unsigned long flags;
-       struct dmabuf *dmabuf;
-       int i, num_ac97;
-
-       if (!card)
-               return 0;
-       spin_lock_irqsave(&card->lock, flags);
-       card->pm_suspended = 1;
-       for (i = 0; i < NR_HW_CH; i++) {
-               state = card->states[i];
-               if (!state)
-                       continue;
-               /* this happens only if there are open files */
-               dmabuf = &state->dmabuf;
-               if (dmabuf->enable & DAC_RUNNING ||
-                   (dmabuf->count
-                    && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) {
-                       state->pm_saved_dac_rate = dmabuf->rate;
-                       stop_dac(state);
-               } else {
-                       state->pm_saved_dac_rate = 0;
-               }
-               if (dmabuf->enable & ADC_RUNNING) {
-                       state->pm_saved_adc_rate = dmabuf->rate;
-                       stop_adc(state);
-               } else {
-                       state->pm_saved_adc_rate = 0;
-               }
-               dmabuf->ready = 0;
-               dmabuf->swptr = dmabuf->hwptr = 0;
-               dmabuf->count = dmabuf->total_bytes = 0;
-       }
-
-       spin_unlock_irqrestore(&card->lock, flags);
-       /* save mixer settings */
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-               struct ac97_codec *codec = card->ac97_codec[num_ac97];
-               if (!codec)
-                       continue;
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if ((supported_mixer(codec, i)) && (codec->read_mixer)) {
-                               card->pm_saved_mixer_settings[i][num_ac97] = codec->read_mixer(codec, i);
-                       }
-               }
-       }
-       pci_save_state(dev);    /* XXX do we need this? */
-       pci_disable_device(dev);        /* disable busmastering */
-       pci_set_power_state(dev, 3);    /* Zzz. */
-       return 0;
-}
-
-
-static int ali_pm_resume(struct pci_dev *dev)
-{
-       int num_ac97, i = 0;
-       struct ali_card *card = pci_get_drvdata(dev);
-       pci_enable_device(dev);
-       pci_restore_state(dev);
-       /* observation of a toshiba portege 3440ct suggests that the 
-          hardware has to be more or less completely reinitialized from
-          scratch after an apm suspend.  Works For Me.   -dan */
-       ali_ac97_random_init_stuff(card);
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-               struct ac97_codec *codec = card->ac97_codec[num_ac97];
-               /* check they haven't stolen the hardware while we were
-                  away */
-               if (!codec || !ali_ac97_exists(card, num_ac97)) {
-                       if (num_ac97)
-                               continue;
-                       else
-                               BUG();
-               }
-               if (!ali_ac97_probe_and_powerup(card, codec))
-                       BUG();
-               if ((card->ac97_features & 0x0001)) {
-                       /* at probe time we found we could do variable
-                          rates, but APM suspend has made it forget
-                          its magical powers */
-                       if (!ali_ac97_enable_variable_rate(codec))
-                               BUG();
-               }
-               /* we lost our mixer settings, so restore them */
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (supported_mixer(codec, i)) {
-                               int val = card->pm_saved_mixer_settings[i][num_ac97];
-                               codec->mixer_state[i] = val;
-                               codec->write_mixer(codec, i,
-                                                  (val & 0xff),
-                                                  ((val >> 8) & 0xff));
-                       }
-               }
-       }
-
-       /* we need to restore the sample rate from whatever it was */
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               if (state) {
-                       if (state->pm_saved_adc_rate)
-                               ali_set_adc_rate(state, state->pm_saved_adc_rate);
-                       if (state->pm_saved_dac_rate)
-                               ali_set_dac_rate(state, state->pm_saved_dac_rate);
-               }
-       }
-
-       card->pm_suspended = 0;
-       /* any processes that were reading/writing during the suspend
-          probably ended up here */
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               if (state)
-                       wake_up(&state->dmabuf.wait);
-       }
-       return 0;
-}
-#endif                         /* CONFIG_PM */
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("ALI 5455 audio support");
-MODULE_LICENSE("GPL");
-module_param(clocking, int, 0);
-/* FIXME: bool? */
-module_param(strict_clocking, uint, 0);
-module_param(codec_pcmout_share_spdif_locked, uint, 0);
-module_param(codec_independent_spdif_locked, uint, 0);
-module_param(controller_pcmout_share_spdif_locked, uint, 0);
-module_param(controller_independent_spdif_locked, uint, 0);
-#define ALI5455_MODULE_NAME "ali5455"
-static struct pci_driver ali_pci_driver = {
-       .name           = ALI5455_MODULE_NAME,
-       .id_table       = ali_pci_tbl,
-       .probe          = ali_probe,
-       .remove         = __devexit_p(ali_remove),
-#ifdef CONFIG_PM
-       .suspend        = ali_pm_suspend,
-       .resume         = ali_pm_resume,
-#endif                         /* CONFIG_PM */
-};
-
-static int __init ali_init_module(void)
-{
-       printk(KERN_INFO "ALI 5455 + AC97 Audio, version "
-              DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
-
-       if (codec_independent_spdif_locked > 0) {
-               if (codec_independent_spdif_locked == 32000
-                   || codec_independent_spdif_locked == 44100
-                   || codec_independent_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_independent_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       codec_independent_spdif_locked = 0;
-               }
-       }
-       if (controller_independent_spdif_locked > 0) {
-               if (controller_independent_spdif_locked == 32000
-                   || controller_independent_spdif_locked == 44100
-                   || controller_independent_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", controller_independent_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       controller_independent_spdif_locked = 0;
-               }
-       }
-
-       if (codec_pcmout_share_spdif_locked > 0) {
-               if (codec_pcmout_share_spdif_locked == 32000
-                   || codec_pcmout_share_spdif_locked == 44100
-                   || codec_pcmout_share_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_pcmout_share_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       codec_pcmout_share_spdif_locked = 0;
-               }
-       }
-       if (controller_pcmout_share_spdif_locked > 0) {
-               if (controller_pcmout_share_spdif_locked == 32000
-                   || controller_pcmout_share_spdif_locked == 44100
-                   || controller_pcmout_share_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling controller S/PDIF at sample rate %dHz.\n", controller_pcmout_share_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       controller_pcmout_share_spdif_locked = 0;
-               }
-       }
-       return pci_register_driver(&ali_pci_driver);
-}
-
-static void __exit ali_cleanup_module(void)
-{
-       pci_unregister_driver(&ali_pci_driver);
-}
-
-module_init(ali_init_module);
-module_exit(ali_cleanup_module);
-/*
-Local Variables:
-c-basic-offset: 8
-End:
-*/
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
deleted file mode 100644 (file)
index e379623..0000000
+++ /dev/null
@@ -1,2216 +0,0 @@
-/*
- *      au1000.c  --  Sound driver for Alchemy Au1000 MIPS Internet Edge
- *                    Processor.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * Module command line parameters:
- *
- *  Supported devices:
- *  /dev/dsp    standard OSS /dev/dsp device
- *  /dev/mixer  standard OSS /dev/mixer device
- *
- * Notes:
- *
- *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
- *     taken, slightly modified or not at all, from the ES1371 driver,
- *     so refer to the credits in es1371.c for those. The rest of the
- *     code (probe, open, read, write, the ISR, etc.) is new.
- *
- *  Revision history
- *    06.27.2001  Initial version
- *    03.20.2002  Added mutex locks around read/write methods, to prevent
- *                simultaneous access on SMP or preemptible kernels. Also
- *                removed the counter/pointer fragment aligning at the end
- *                of read/write methods [stevel].
- *    03.21.2002  Add support for coherent DMA on the audio read/write DMA
- *                channels [stevel].
- *
- */
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/init.h>
-#include <linux/page-flags.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef AU1000_DEBUG
-#undef AU1000_VERBOSE_DEBUG
-
-#define AU1000_MODULE_NAME "Au1000 audio"
-#define PFX AU1000_MODULE_NAME
-
-#ifdef AU1000_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-
-/* misc stuff */
-#define POLL_COUNT   0x5000
-#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
-
-/* Boot options */
-static int      vra = 0;       // 0 = no VRA, 1 = use VRA if codec supports it
-module_param(vra, bool, 0);
-MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
-
-
-/* --------------------------------------------------------------------- */
-
-struct au1000_state {
-       /* soundcore stuff */
-       int             dev_audio;
-
-#ifdef AU1000_DEBUG
-       /* debug /proc entry */
-       struct proc_dir_entry *ps;
-       struct proc_dir_entry *ac97_ps;
-#endif                         /* AU1000_DEBUG */
-
-       struct ac97_codec codec;
-       unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
-       unsigned        codec_ext_caps; // AC'97 reg 28h, "Extended Audio ID"
-       int             no_vra; // do not use VRA
-
-       spinlock_t      lock;
-       struct mutex open_mutex;
-       struct mutex sem;
-       mode_t          open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               unsigned int    dmanr;  // DMA Channel number
-               unsigned        sample_rate;    // Hz
-               unsigned src_factor;     // SRC interp/decimation (no vra)
-               unsigned        sample_size;    // 8 or 16
-               int             num_channels;   // 1 = mono, 2 = stereo, 4, 6
-               int dma_bytes_per_sample;// DMA bytes per audio sample frame
-               int user_bytes_per_sample;// User bytes per audio sample frame
-               int cnt_factor;          // user-to-DMA bytes per audio
-               //  sample frame
-               void           *rawbuf;
-               dma_addr_t      dmaaddr;
-               unsigned        buforder;
-               unsigned numfrag;        // # of DMA fragments in DMA buffer
-               unsigned        fragshift;
-               void           *nextIn; // ptr to next-in to DMA buffer
-               void           *nextOut;// ptr to next-out from DMA buffer
-               int             count;  // current byte count in DMA buffer
-               unsigned        total_bytes;    // total bytes written or read
-               unsigned        error;  // over/underrun
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;       // user perception of fragment size
-               unsigned dma_fragsize;   // DMA (real) fragment size
-               unsigned dmasize;        // Total DMA buffer size
-               //   (mult. of DMA fragsize)
-               /* OSS stuff */
-               unsigned        mapped:1;
-               unsigned        ready:1;
-               unsigned        stopped:1;
-               unsigned        ossfragshift;
-               int             ossmaxfrags;
-               unsigned        subdivision;
-       } dma_dac      , dma_adc;
-} au1000_state;
-
-/* --------------------------------------------------------------------- */
-
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned        r = 0;
-
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void au1000_delay(int msec)
-{
-       unsigned long   tmo;
-       signed long     tmo2;
-
-       if (in_interrupt())
-               return;
-
-       tmo = jiffies + (msec * HZ) / 1000;
-       for (;;) {
-               tmo2 = tmo - jiffies;
-               if (tmo2 <= 0)
-                       break;
-               schedule_timeout(tmo2);
-       }
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-       struct au1000_state *s = (struct au1000_state *)codec->private_data;
-       unsigned long   flags;
-       u32             cmd;
-       u16             data;
-       int             i;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT)
-               err("rdcodec: codec cmd pending expired!");
-
-       cmd = (u32) addr & AC97C_INDEX_MASK;
-       cmd |= AC97C_READ;      // read command
-       au_writel(cmd, AC97C_CMD);
-
-       /* now wait for the data */
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT) {
-               err("rdcodec: read poll expired!");
-               return 0;
-       }
-
-       data = au_readl(AC97C_CMD) & 0xffff;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       return data;
-}
-
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-       struct au1000_state *s = (struct au1000_state *)codec->private_data;
-       unsigned long   flags;
-       u32             cmd;
-       int             i;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT)
-               err("wrcodec: codec cmd pending expired!");
-
-       cmd = (u32) addr & AC97C_INDEX_MASK;
-       cmd &= ~AC97C_READ;     // write command
-       cmd |= ((u32) data << AC97C_WD_BIT);    // OR in the data word
-       au_writel(cmd, AC97C_CMD);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void waitcodec(struct ac97_codec *codec)
-{
-       u16             temp;
-       int             i;
-
-       /* codec_wait is used to wait for a ready state after
-          an AC97C_RESET. */
-       au1000_delay(10);
-
-       // first poll the CODEC_READY tag bit
-       for (i = 0; i < POLL_COUNT; i++)
-               if (au_readl(AC97C_STATUS) & AC97C_READY)
-                       break;
-       if (i == POLL_COUNT) {
-               err("waitcodec: CODEC_READY poll expired!");
-               return;
-       }
-       // get AC'97 powerdown control/status register
-       temp = rdcodec(codec, AC97_POWER_CONTROL);
-
-       // If anything is powered down, power'em up
-       if (temp & 0x7f00) {
-               // Power on
-               wrcodec(codec, AC97_POWER_CONTROL, 0);
-               au1000_delay(100);
-               // Reread
-               temp = rdcodec(codec, AC97_POWER_CONTROL);
-       }
-    
-       // Check if Codec REF,ANL,DAC,ADC ready
-       if ((temp & 0x7f0f) != 0x000f)
-               err("codec reg 26 status (0x%x) not ready!!", temp);
-}
-
-
-/* --------------------------------------------------------------------- */
-
-/* stop the ADC before calling */
-static void set_adc_rate(struct au1000_state *s, unsigned rate)
-{
-       struct dmabuf  *adc = &s->dma_adc;
-       struct dmabuf  *dac = &s->dma_dac;
-       unsigned        adc_rate, dac_rate;
-       u16             ac97_extstat;
-
-       if (s->no_vra) {
-               // calc SRC factor
-               adc->src_factor = ((96000 / rate) + 1) >> 1;
-               adc->sample_rate = 48000 / adc->src_factor;
-               return;
-       }
-
-       adc->src_factor = 1;
-
-       ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-       rate = rate > 48000 ? 48000 : rate;
-
-       // enable VRA
-       wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-               ac97_extstat | AC97_EXTSTAT_VRA);
-       // now write the sample rate
-       wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
-       // read it back for actual supported rate
-       adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("%s: set to %d Hz", __FUNCTION__, adc_rate);
-#endif
-
-       // some codec's don't allow unequal DAC and ADC rates, in which case
-       // writing one rate reg actually changes both.
-       dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-       if (dac->num_channels > 2)
-               wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
-       if (dac->num_channels > 4)
-               wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
-
-       adc->sample_rate = adc_rate;
-       dac->sample_rate = dac_rate;
-}
-
-/* stop the DAC before calling */
-static void set_dac_rate(struct au1000_state *s, unsigned rate)
-{
-       struct dmabuf  *dac = &s->dma_dac;
-       struct dmabuf  *adc = &s->dma_adc;
-       unsigned        adc_rate, dac_rate;
-       u16             ac97_extstat;
-
-       if (s->no_vra) {
-               // calc SRC factor
-               dac->src_factor = ((96000 / rate) + 1) >> 1;
-               dac->sample_rate = 48000 / dac->src_factor;
-               return;
-       }
-
-       dac->src_factor = 1;
-
-       ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-       rate = rate > 48000 ? 48000 : rate;
-
-       // enable VRA
-       wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-               ac97_extstat | AC97_EXTSTAT_VRA);
-       // now write the sample rate
-       wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
-       // I don't support different sample rates for multichannel,
-       // so make these channels the same.
-       if (dac->num_channels > 2)
-               wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
-       if (dac->num_channels > 4)
-               wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
-       // read it back for actual supported rate
-       dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("%s: set to %d Hz", __FUNCTION__, dac_rate);
-#endif
-
-       // some codec's don't allow unequal DAC and ADC rates, in which case
-       // writing one rate reg actually changes both.
-       adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-       dac->sample_rate = dac_rate;
-       adc->sample_rate = adc_rate;
-}
-
-static void stop_dac(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_dac;
-       unsigned long   flags;
-
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       disable_dma(db->dmanr);
-
-       db->stopped = 1;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void  stop_adc(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_adc;
-       unsigned long   flags;
-
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       disable_dma(db->dmanr);
-
-       db->stopped = 1;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_xmit_slots(int num_channels)
-{
-       u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_XMIT_SLOTS_MASK;
-
-       switch (num_channels) {
-       case 1:         // mono
-       case 2:         // stereo, slots 3,4
-               ac97_config |= (0x3 << AC97C_XMIT_SLOTS_BIT);
-               break;
-       case 4:         // stereo with surround, slots 3,4,7,8
-               ac97_config |= (0x33 << AC97C_XMIT_SLOTS_BIT);
-               break;
-       case 6:         // stereo with surround and center/LFE, slots 3,4,6,7,8,9
-               ac97_config |= (0x7b << AC97C_XMIT_SLOTS_BIT);
-               break;
-       }
-
-       au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void     set_recv_slots(int num_channels)
-{
-       u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_RECV_SLOTS_MASK;
-
-       /*
-        * Always enable slots 3 and 4 (stereo). Slot 6 is
-        * optional Mic ADC, which I don't support yet.
-        */
-       ac97_config |= (0x3 << AC97C_RECV_SLOTS_BIT);
-
-       au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void start_dac(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_dac;
-       unsigned long   flags;
-       unsigned long   buf1, buf2;
-
-       if (!db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       au_readl(AC97C_STATUS); // read status to clear sticky bits
-
-       // reset Buffer 1 and 2 pointers to nextOut and nextOut+dma_fragsize
-       buf1 = virt_to_phys(db->nextOut);
-       buf2 = buf1 + db->dma_fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-
-       set_xmit_slots(db->num_channels);
-
-       init_dma(db->dmanr);
-       if (get_dma_active_buffer(db->dmanr) == 0) {
-               clear_dma_done0(db->dmanr);     // clear DMA done bit
-               set_dma_addr0(db->dmanr, buf1);
-               set_dma_addr1(db->dmanr, buf2);
-       } else {
-               clear_dma_done1(db->dmanr);     // clear DMA done bit
-               set_dma_addr1(db->dmanr, buf1);
-               set_dma_addr0(db->dmanr, buf2);
-       }
-       set_dma_count(db->dmanr, db->dma_fragsize>>1);
-       enable_dma_buffers(db->dmanr);
-
-       start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dump_au1000_dma_channel(db->dmanr);
-#endif
-
-       db->stopped = 0;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_adc;
-       unsigned long   flags;
-       unsigned long   buf1, buf2;
-
-       if (!db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       au_readl(AC97C_STATUS); // read status to clear sticky bits
-
-       // reset Buffer 1 and 2 pointers to nextIn and nextIn+dma_fragsize
-       buf1 = virt_to_phys(db->nextIn);
-       buf2 = buf1 + db->dma_fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-
-       set_recv_slots(db->num_channels);
-
-       init_dma(db->dmanr);
-       if (get_dma_active_buffer(db->dmanr) == 0) {
-               clear_dma_done0(db->dmanr);     // clear DMA done bit
-               set_dma_addr0(db->dmanr, buf1);
-               set_dma_addr1(db->dmanr, buf2);
-       } else {
-               clear_dma_done1(db->dmanr);     // clear DMA done bit
-               set_dma_addr1(db->dmanr, buf1);
-               set_dma_addr0(db->dmanr, buf2);
-       }
-       set_dma_count(db->dmanr, db->dma_fragsize>>1);
-       enable_dma_buffers(db->dmanr);
-
-       start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dump_au1000_dma_channel(db->dmanr);
-#endif
-
-       db->stopped = 0;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-       struct page    *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf +
-                                   (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               dma_free_noncoherent(NULL,
-                               PAGE_SIZE << db->buforder,
-                               db->rawbuf,
-                               db->dmaaddr);
-       }
-       db->rawbuf = db->nextIn = db->nextOut = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-       int             order;
-       unsigned user_bytes_per_sec;
-       unsigned        bufs;
-       struct page    *page, *pend;
-       unsigned        rate = db->sample_rate;
-
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER;
-                    order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = dma_alloc_noncoherent(NULL,
-                                               PAGE_SIZE << order,
-                                               &db->dmaaddr,
-                                               0)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved;
-                  otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf +
-                                   (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-
-       db->cnt_factor = 1;
-       if (db->sample_size == 8)
-               db->cnt_factor *= 2;
-       if (db->num_channels == 1)
-               db->cnt_factor *= 2;
-       db->cnt_factor *= db->src_factor;
-
-       db->count = 0;
-       db->nextIn = db->nextOut = db->rawbuf;
-
-       db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
-       db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
-                                       2 : db->num_channels);
-
-       user_bytes_per_sec = rate * db->user_bytes_per_sample;
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < user_bytes_per_sec)
-                       db->fragshift = ld2(user_bytes_per_sec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(user_bytes_per_sec / 100 /
-                                   (db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-
-       db->fragsize = 1 << db->fragshift;
-       db->dma_fragsize = db->fragsize * db->cnt_factor;
-       db->numfrag = bufs / db->dma_fragsize;
-
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->fragsize = 1 << db->fragshift;
-               db->dma_fragsize = db->fragsize * db->cnt_factor;
-               db->numfrag = bufs / db->dma_fragsize;
-       }
-
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-
-       db->dmasize = db->dma_fragsize * db->numfrag;
-       memset(db->rawbuf, 0, bufs);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("rate=%d, samplesize=%d, channels=%d",
-           rate, db->sample_size, db->num_channels);
-       dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
-           db->fragsize, db->cnt_factor, db->dma_fragsize);
-       dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
-#endif
-
-       db->ready = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct au1000_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc);
-
-}
-
-static inline int prog_dmabuf_dac(struct au1000_state *s)
-{
-       stop_dac(s);
-       return prog_dmabuf(s, &s->dma_dac);
-}
-
-
-/* hold spinlock for the following */
-static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct au1000_state *s = (struct au1000_state *) dev_id;
-       struct dmabuf  *dac = &s->dma_dac;
-       unsigned long   newptr;
-       u32 ac97c_stat, buff_done;
-
-       ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-       if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
-               dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-       if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
-               /* fastpath out, to ease interrupt sharing */
-               return IRQ_HANDLED;
-       }
-
-       spin_lock(&s->lock);
-       
-       if (buff_done != (DMA_D0 | DMA_D1)) {
-               dac->nextOut += dac->dma_fragsize;
-               if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-                       dac->nextOut -= dac->dmasize;
-
-               /* update playback pointers */
-               newptr = virt_to_phys(dac->nextOut) + dac->dma_fragsize;
-               if (newptr >= dac->dmaaddr + dac->dmasize)
-                       newptr -= dac->dmasize;
-
-               dac->count -= dac->dma_fragsize;
-               dac->total_bytes += dac->dma_fragsize;
-
-               if (dac->count <= 0) {
-#ifdef AU1000_VERBOSE_DEBUG
-                       dbg("dac underrun");
-#endif
-                       spin_unlock(&s->lock);
-                       stop_dac(s);
-                       spin_lock(&s->lock);
-                       dac->count = 0;
-                       dac->nextIn = dac->nextOut;
-               } else if (buff_done == DMA_D0) {
-                       clear_dma_done0(dac->dmanr);    // clear DMA done bit
-                       set_dma_count0(dac->dmanr, dac->dma_fragsize>>1);
-                       set_dma_addr0(dac->dmanr, newptr);
-                       enable_dma_buffer0(dac->dmanr); // reenable
-               } else {
-                       clear_dma_done1(dac->dmanr);    // clear DMA done bit
-                       set_dma_count1(dac->dmanr, dac->dma_fragsize>>1);
-                       set_dma_addr1(dac->dmanr, newptr);
-                       enable_dma_buffer1(dac->dmanr); // reenable
-               }
-       } else {
-               // both done bits set, we missed an interrupt
-               spin_unlock(&s->lock);
-               stop_dac(s);
-               spin_lock(&s->lock);
-
-               dac->nextOut += 2*dac->dma_fragsize;
-               if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-                       dac->nextOut -= dac->dmasize;
-
-               dac->count -= 2*dac->dma_fragsize;
-               dac->total_bytes += 2*dac->dma_fragsize;
-
-               if (dac->count > 0) {
-                       spin_unlock(&s->lock);
-                       start_dac(s);
-                       spin_lock(&s->lock);
-               }
-       }
-
-       /* wake up anybody listening */
-       if (waitqueue_active(&dac->wait))
-               wake_up(&dac->wait);
-
-       spin_unlock(&s->lock);
-
-       return IRQ_HANDLED;
-}
-
-
-static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct au1000_state *s = (struct au1000_state *) dev_id;
-       struct dmabuf  *adc = &s->dma_adc;
-       unsigned long   newptr;
-       u32 ac97c_stat, buff_done;
-
-       ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-       if (ac97c_stat & (AC97C_RU | AC97C_RO))
-               dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-       if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
-               /* fastpath out, to ease interrupt sharing */
-               return IRQ_HANDLED;
-       }
-
-       spin_lock(&s->lock);
-       
-       if (buff_done != (DMA_D0 | DMA_D1)) {
-               if (adc->count + adc->dma_fragsize > adc->dmasize) {
-                       // Overrun. Stop ADC and log the error
-                       spin_unlock(&s->lock);
-                       stop_adc(s);
-                       adc->error++;
-                       err("adc overrun");
-                       return IRQ_NONE;
-               }
-
-               adc->nextIn += adc->dma_fragsize;
-               if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-                       adc->nextIn -= adc->dmasize;
-
-               /* update capture pointers */
-               newptr = virt_to_phys(adc->nextIn) + adc->dma_fragsize;
-               if (newptr >= adc->dmaaddr + adc->dmasize)
-                       newptr -= adc->dmasize;
-
-               adc->count += adc->dma_fragsize;
-               adc->total_bytes += adc->dma_fragsize;
-
-               if (buff_done == DMA_D0) {
-                       clear_dma_done0(adc->dmanr);    // clear DMA done bit
-                       set_dma_count0(adc->dmanr, adc->dma_fragsize>>1);
-                       set_dma_addr0(adc->dmanr, newptr);
-                       enable_dma_buffer0(adc->dmanr); // reenable
-               } else {
-                       clear_dma_done1(adc->dmanr);    // clear DMA done bit
-                       set_dma_count1(adc->dmanr, adc->dma_fragsize>>1);
-                       set_dma_addr1(adc->dmanr, newptr);
-                       enable_dma_buffer1(adc->dmanr); // reenable
-               }
-       } else {
-               // both done bits set, we missed an interrupt
-               spin_unlock(&s->lock);
-               stop_adc(s);
-               spin_lock(&s->lock);
-               
-               if (adc->count + 2*adc->dma_fragsize > adc->dmasize) {
-                       // Overrun. Log the error
-                       adc->error++;
-                       err("adc overrun");
-                       spin_unlock(&s->lock);
-                       return IRQ_NONE;
-               }
-
-               adc->nextIn += 2*adc->dma_fragsize;
-               if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-                       adc->nextIn -= adc->dmasize;
-
-               adc->count += 2*adc->dma_fragsize;
-               adc->total_bytes += 2*adc->dma_fragsize;
-               
-               spin_unlock(&s->lock);
-               start_adc(s);
-               spin_lock(&s->lock);
-       }
-
-       /* wake up anybody listening */
-       if (waitqueue_active(&adc->wait))
-               wake_up(&adc->wait);
-
-       spin_unlock(&s->lock);
-
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static loff_t au1000_llseek(struct file *file, loff_t offset, int origin)
-{
-       return -ESPIPE;
-}
-
-
-static int au1000_open_mixdev(struct inode *inode, struct file *file)
-{
-       file->private_data = &au1000_state;
-       return nonseekable_open(inode, file);
-}
-
-static int au1000_release_mixdev(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
-                        unsigned long arg)
-{
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int au1000_ioctl_mixdev(struct inode *inode, struct file *file,
-                              unsigned int cmd, unsigned long arg)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct ac97_codec *codec = &s->codec;
-
-       return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations au1000_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = au1000_llseek,
-       .ioctl          = au1000_ioctl_mixdev,
-       .open           = au1000_open_mixdev,
-       .release        = au1000_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct au1000_state *s, int nonblock)
-{
-       unsigned long   flags;
-       int             count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
-               return 0;
-
-       for (;;) {
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                       break;
-               if (nonblock)
-                       return -EBUSY;
-               tmo = 1000 * count / (s->no_vra ?
-                                     48000 : s->dma_dac.sample_rate);
-               tmo /= s->dma_dac.dma_bytes_per_sample;
-               au1000_delay(tmo);
-       }
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline u8 S16_TO_U8(s16 ch)
-{
-       return (u8) (ch >> 8) + 0x80;
-}
-static inline s16 U8_TO_S16(u8 ch)
-{
-       return (s16) (ch - 0x80) << 8;
-}
-
-/*
- * Translates user samples to dma buffer suitable for AC'97 DAC data:
- *     If mono, copy left channel to right channel in dma buffer.
- *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
- *     If interpolating (no VRA), duplicate every audio frame src_factor times.
- */
-static int translate_from_user(struct dmabuf *db,
-                              char* dmabuf,
-                              char* userbuf,
-                              int dmacount)
-{
-       int             sample, i;
-       int             interp_bytes_per_sample;
-       int             num_samples;
-       int             mono = (db->num_channels == 1);
-       char            usersample[12];
-       s16             ch, dmasample[6];
-
-       if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-               // no translation necessary, just copy
-               if (copy_from_user(dmabuf, userbuf, dmacount))
-                       return -EFAULT;
-               return dmacount;
-       }
-
-       interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-       num_samples = dmacount / interp_bytes_per_sample;
-
-       for (sample = 0; sample < num_samples; sample++) {
-               if (copy_from_user(usersample, userbuf,
-                                  db->user_bytes_per_sample)) {
-                       dbg("%s: fault", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               for (i = 0; i < db->num_channels; i++) {
-                       if (db->sample_size == 8)
-                               ch = U8_TO_S16(usersample[i]);
-                       else
-                               ch = *((s16 *) (&usersample[i * 2]));
-                       dmasample[i] = ch;
-                       if (mono)
-                               dmasample[i + 1] = ch;  // right channel
-               }
-
-               // duplicate every audio frame src_factor times
-               for (i = 0; i < db->src_factor; i++)
-                       memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
-
-               userbuf += db->user_bytes_per_sample;
-               dmabuf += interp_bytes_per_sample;
-       }
-
-       return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Translates AC'97 ADC samples to user buffer:
- *     If mono, send only left channel to user buffer.
- *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
- *     If decimating (no VRA), skip over src_factor audio frames.
- */
-static int translate_to_user(struct dmabuf *db,
-                            char* userbuf,
-                            char* dmabuf,
-                            int dmacount)
-{
-       int             sample, i;
-       int             interp_bytes_per_sample;
-       int             num_samples;
-       int             mono = (db->num_channels == 1);
-       char            usersample[12];
-
-       if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-               // no translation necessary, just copy
-               if (copy_to_user(userbuf, dmabuf, dmacount))
-                       return -EFAULT;
-               return dmacount;
-       }
-
-       interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-       num_samples = dmacount / interp_bytes_per_sample;
-
-       for (sample = 0; sample < num_samples; sample++) {
-               for (i = 0; i < db->num_channels; i++) {
-                       if (db->sample_size == 8)
-                               usersample[i] =
-                                       S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
-                       else
-                               *((s16 *) (&usersample[i * 2])) =
-                                       *((s16 *) (&dmabuf[i * 2]));
-               }
-
-               if (copy_to_user(userbuf, usersample,
-                                db->user_bytes_per_sample)) {
-                       dbg("%s: fault", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               userbuf += db->user_bytes_per_sample;
-               dmabuf += interp_bytes_per_sample;
-       }
-
-       return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Copy audio data to/from user buffer from/to dma buffer, taking care
- * that we wrap when reading/writing the dma buffer. Returns actual byte
- * count written to or read from the dma buffer.
- */
-static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
-                           int count, int to_user)
-{
-       char           *bufptr = to_user ? db->nextOut : db->nextIn;
-       char           *bufend = db->rawbuf + db->dmasize;
-       int             cnt, ret;
-
-       if (bufptr + count > bufend) {
-               int             partial = (int) (bufend - bufptr);
-               if (to_user) {
-                       if ((cnt = translate_to_user(db, userbuf,
-                                                    bufptr, partial)) < 0)
-                               return cnt;
-                       ret = cnt;
-                       if ((cnt = translate_to_user(db, userbuf + partial,
-                                                    db->rawbuf,
-                                                    count - partial)) < 0)
-                               return cnt;
-                       ret += cnt;
-               } else {
-                       if ((cnt = translate_from_user(db, bufptr, userbuf,
-                                                      partial)) < 0)
-                               return cnt;
-                       ret = cnt;
-                       if ((cnt = translate_from_user(db, db->rawbuf,
-                                                      userbuf + partial,
-                                                      count - partial)) < 0)
-                               return cnt;
-                       ret += cnt;
-               }
-       } else {
-               if (to_user)
-                       ret = translate_to_user(db, userbuf, bufptr, count);
-               else
-                       ret = translate_from_user(db, bufptr, userbuf, count);
-       }
-
-       return ret;
-}
-
-
-static ssize_t au1000_read(struct file *file, char *buffer,
-                          size_t count, loff_t *ppos)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db = &s->dma_adc;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t         ret;
-       unsigned long   flags;
-       int             cnt, usercnt, avail;
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-       count *= db->cnt_factor;
-
-       mutex_lock(&s->sem);
-       add_wait_queue(&db->wait, &wait);
-
-       while (count > 0) {
-               // wait for samples in ADC dma buffer
-               do {
-                       if (db->stopped)
-                               start_adc(s);
-                       spin_lock_irqsave(&s->lock, flags);
-                       avail = db->count;
-                       if (avail <= 0)
-                               __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       goto out;
-                               }
-                               mutex_unlock(&s->sem);
-                               schedule();
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       goto out2;
-                               }
-                               mutex_lock(&s->sem);
-                       }
-               } while (avail <= 0);
-
-               // copy from nextOut to user
-               if ((cnt = copy_dmabuf_user(db, buffer,
-                                           count > avail ?
-                                           avail : count, 1)) < 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count -= cnt;
-               db->nextOut += cnt;
-               if (db->nextOut >= db->rawbuf + db->dmasize)
-                       db->nextOut -= db->dmasize;
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               count -= cnt;
-               usercnt = cnt / db->cnt_factor;
-               buffer += usercnt;
-               ret += usercnt;
-       }                       // while (count > 0)
-
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&db->wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t au1000_write(struct file *file, const char *buffer,
-                           size_t count, loff_t * ppos)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db = &s->dma_dac;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t         ret = 0;
-       unsigned long   flags;
-       int             cnt, usercnt, avail;
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("write: count=%d", count);
-#endif
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-
-       count *= db->cnt_factor;
-
-       mutex_lock(&s->sem);
-       add_wait_queue(&db->wait, &wait);
-
-       while (count > 0) {
-               // wait for space in playback buffer
-               do {
-                       spin_lock_irqsave(&s->lock, flags);
-                       avail = (int) db->dmasize - db->count;
-                       if (avail <= 0)
-                               __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       goto out;
-                               }
-                               mutex_unlock(&s->sem);
-                               schedule();
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       goto out2;
-                               }
-                               mutex_lock(&s->sem);
-                       }
-               } while (avail <= 0);
-
-               // copy from user to nextIn
-               if ((cnt = copy_dmabuf_user(db, (char *) buffer,
-                                           count > avail ?
-                                           avail : count, 0)) < 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count += cnt;
-               db->nextIn += cnt;
-               if (db->nextIn >= db->rawbuf + db->dmasize)
-                       db->nextIn -= db->dmasize;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (db->stopped)
-                       start_dac(s);
-
-               count -= cnt;
-               usercnt = cnt / db->cnt_factor;
-               buffer += usercnt;
-               ret += usercnt;
-       }                       // while (count > 0)
-
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&db->wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int au1000_poll(struct file *file,
-                               struct poll_table_struct *wait)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       unsigned long   flags;
-       unsigned int    mask = 0;
-
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready)
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready)
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-
-       spin_lock_irqsave(&s->lock, flags);
-       
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >=
-                           (signed)s->dma_dac.dma_fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed) s->dma_dac.dmasize >=
-                           s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db;
-       unsigned long   size;
-       int ret = 0;
-
-       dbg("%s", __FUNCTION__);
-    
-       lock_kernel();
-       mutex_lock(&s->sem);
-       if (vma->vm_flags & VM_WRITE)
-               db = &s->dma_dac;
-       else if (vma->vm_flags & VM_READ)
-               db = &s->dma_adc;
-       else {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
-                            size, vma->vm_page_prot)) {
-               ret = -EAGAIN;
-               goto out;
-       }
-       vma->vm_flags &= ~VM_IO;
-       db->mapped = 1;
-out:
-       mutex_unlock(&s->sem);
-       unlock_kernel();
-       return ret;
-}
-
-
-#ifdef AU1000_VERBOSE_DEBUG
-static struct ioctl_str_t {
-       unsigned int    cmd;
-       const char     *str;
-} ioctl_str[] = {
-       {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
-       {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
-       {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
-       {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
-       {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
-       {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
-       {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
-       {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
-       {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
-       {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
-       {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
-       {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
-       {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
-       {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
-       {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
-       {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
-       {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
-       {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
-       {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
-       {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
-       {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
-       {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
-       {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
-       {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
-       {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
-       {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
-       {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
-       {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
-       {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
-       {OSS_GETVERSION, "OSS_GETVERSION"},
-       {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
-       {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
-       {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
-       {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
-};
-#endif
-
-// Need to hold a spin-lock before calling this!
-static int dma_count_done(struct dmabuf *db)
-{
-       if (db->stopped)
-               return 0;
-
-       return db->dma_fragsize - get_dma_residue(db->dmanr);
-}
-
-
-static int au1000_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       unsigned long   flags;
-       audio_buf_info  abinfo;
-       count_info      cinfo;
-       int             count;
-       int             val, mapped, ret, diff;
-
-       mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
-               if (ioctl_str[count].cmd == cmd)
-                       break;
-       }
-       if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
-               dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
-       else
-               dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
-#endif
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *) arg);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, file->f_flags & O_NONBLOCK);
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-                               DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
-
-       case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq();
-                       s->dma_dac.count = s->dma_dac.total_bytes = 0;
-                       s->dma_dac.nextIn = s->dma_dac.nextOut =
-                               s->dma_dac.rawbuf;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq();
-                       s->dma_adc.count = s->dma_adc.total_bytes = 0;
-                       s->dma_adc.nextIn = s->dma_adc.nextOut =
-                               s->dma_adc.rawbuf;
-               }
-               return 0;
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               set_dac_rate(s, val);
-                       }
-                       if (s->open_mode & FMODE_READ)
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       if (s->open_mode & FMODE_WRITE)
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-               }
-               return put_user((file->f_mode & FMODE_READ) ?
-                               s->dma_adc.sample_rate :
-                               s->dma_dac.sample_rate,
-                               (int *)arg);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.num_channels = val ? 2 : 1;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.num_channels = val ? 2 : 1;
-                       if (s->codec_ext_caps & AC97_EXT_DACS) {
-                               // disable surround and center/lfe in AC'97
-                               u16 ext_stat = rdcodec(&s->codec,
-                                                      AC97_EXTENDED_STATUS);
-                               wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-                                       ext_stat | (AC97_EXTSTAT_PRI |
-                                                   AC97_EXTSTAT_PRJ |
-                                                   AC97_EXTSTAT_PRK));
-                       }
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               if (val < 0 || val > 2)
-                                       return -EINVAL;
-                               stop_adc(s);
-                               s->dma_adc.num_channels = val;
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               switch (val) {
-                               case 1:
-                               case 2:
-                                       break;
-                               case 3:
-                               case 5:
-                                       return -EINVAL;
-                               case 4:
-                                       if (!(s->codec_ext_caps &
-                                             AC97_EXTID_SDAC))
-                                               return -EINVAL;
-                                       break;
-                               case 6:
-                                       if ((s->codec_ext_caps &
-                                            AC97_EXT_DACS) != AC97_EXT_DACS)
-                                               return -EINVAL;
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
-
-                               stop_dac(s);
-                               if (val <= 2 &&
-                                   (s->codec_ext_caps & AC97_EXT_DACS)) {
-                                       // disable surround and center/lfe
-                                       // channels in AC'97
-                                       u16             ext_stat =
-                                               rdcodec(&s->codec,
-                                                       AC97_EXTENDED_STATUS);
-                                       wrcodec(&s->codec,
-                                               AC97_EXTENDED_STATUS,
-                                               ext_stat | (AC97_EXTSTAT_PRI |
-                                                           AC97_EXTSTAT_PRJ |
-                                                           AC97_EXTSTAT_PRK));
-                               } else if (val >= 4) {
-                                       // enable surround, center/lfe
-                                       // channels in AC'97
-                                       u16             ext_stat =
-                                               rdcodec(&s->codec,
-                                                       AC97_EXTENDED_STATUS);
-                                       ext_stat &= ~AC97_EXTSTAT_PRJ;
-                                       if (val == 6)
-                                               ext_stat &=
-                                                       ~(AC97_EXTSTAT_PRI |
-                                                         AC97_EXTSTAT_PRK);
-                                       wrcodec(&s->codec,
-                                               AC97_EXTENDED_STATUS,
-                                               ext_stat);
-                               }
-
-                               s->dma_dac.num_channels = val;
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               }
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_GETFMTS:        /* Returns a mask */
-               return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               if (val == AFMT_S16_LE)
-                                       s->dma_adc.sample_size = 16;
-                               else {
-                                       val = AFMT_U8;
-                                       s->dma_adc.sample_size = 8;
-                               }
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               if (val == AFMT_S16_LE)
-                                       s->dma_dac.sample_size = 16;
-                               else {
-                                       val = AFMT_U8;
-                                       s->dma_dac.sample_size = 8;
-                               }
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               } else {
-                       if (file->f_mode & FMODE_READ)
-                               val = (s->dma_adc.sample_size == 16) ?
-                                       AFMT_S16_LE : AFMT_U8;
-                       else
-                               val = (s->dma_dac.sample_size == 16) ?
-                                       AFMT_S16_LE : AFMT_U8;
-               }
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_POST:
-               return 0;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               spin_lock_irqsave(&s->lock, flags);
-               if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
-                       val |= PCM_ENABLE_OUTPUT;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT)
-                               start_adc(s);
-                       else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT)
-                               start_dac(s);
-                       else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               abinfo.fragsize = s->dma_dac.fragsize;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               count -= dma_count_done(&s->dma_dac);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               abinfo.bytes = (s->dma_dac.dmasize - count) /
-                       s->dma_dac.cnt_factor;
-               abinfo.fragstotal = s->dma_dac.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-#ifdef AU1000_VERBOSE_DEBUG
-               dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
-#endif
-               return copy_to_user((void *) arg, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               abinfo.fragsize = s->dma_adc.fragsize;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_adc.count;
-               count += dma_count_done(&s->dma_adc);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               abinfo.bytes = count / s->dma_adc.cnt_factor;
-               abinfo.fragstotal = s->dma_adc.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-               return copy_to_user((void *) arg, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               count -= dma_count_done(&s->dma_dac);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               count /= s->dma_dac.cnt_factor;
-               return put_user(count, (int *) arg);
-
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (!s->dma_adc.stopped) {
-                       diff = dma_count_done(&s->dma_adc);
-                       count += diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
-                               s->dma_adc.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
-                               s->dma_adc.dmaaddr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_adc.fragshift;
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (!s->dma_dac.stopped) {
-                       diff = dma_count_done(&s->dma_dac);
-                       count -= diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
-                               s->dma_dac.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
-                               s->dma_dac.dmaaddr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_dac.fragshift;
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->dma_dac.fragsize, (int *) arg);
-               else
-                       return put_user(s->dma_adc.fragsize, (int *) arg);
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.subdivision = val;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.subdivision = val;
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ?
-                               s->dma_adc.sample_rate :
-                               s->dma_dac.sample_rate,
-                               (int *)arg);
-
-       case SOUND_PCM_READ_CHANNELS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->dma_adc.num_channels, (int *)arg);
-               else
-                       return put_user(s->dma_dac.num_channels, (int *)arg);
-
-       case SOUND_PCM_READ_BITS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->dma_adc.sample_size, (int *)arg);
-               else
-                       return put_user(s->dma_dac.sample_size, (int *)arg);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-
-       return mixdev_ioctl(&s->codec, cmd, arg);
-}
-
-
-static int  au1000_open(struct inode *inode, struct file *file)
-{
-       int             minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct au1000_state *s = &au1000_state;
-       int             ret;
-
-#ifdef AU1000_VERBOSE_DEBUG
-       if (file->f_flags & O_NONBLOCK)
-               dbg("%s: non-blocking", __FUNCTION__);
-       else
-               dbg("%s: blocking", __FUNCTION__);
-#endif
-       
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-
-       stop_dac(s);
-       stop_adc(s);
-
-       if (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-                       s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-               s->dma_adc.num_channels = 1;
-               s->dma_adc.sample_size = 8;
-               set_adc_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->dma_adc.sample_size = 16;
-       }
-
-       if (file->f_mode & FMODE_WRITE) {
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-                       s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
-               s->dma_dac.num_channels = 1;
-               s->dma_dac.sample_size = 8;
-               set_dac_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->dma_dac.sample_size = 16;
-       }
-
-       if (file->f_mode & FMODE_READ) {
-               if ((ret = prog_dmabuf_adc(s)))
-                       return ret;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)))
-                       return ret;
-       }
-
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       mutex_init(&s->sem);
-       return nonseekable_open(inode, file);
-}
-
-static int au1000_release(struct inode *inode, struct file *file)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-
-       lock_kernel();
-       
-       if (file->f_mode & FMODE_WRITE) {
-               unlock_kernel();
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-               lock_kernel();
-       }
-
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const */ struct file_operations au1000_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = au1000_llseek,
-       .read           = au1000_read,
-       .write          = au1000_write,
-       .poll           = au1000_poll,
-       .ioctl          = au1000_ioctl,
-       .mmap           = au1000_mmap,
-       .open           = au1000_open,
-       .release        = au1000_release,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef AU1000_DEBUG
-static int proc_au1000_dump(char *buf, char **start, off_t fpos,
-                           int length, int *eof, void *data)
-{
-       struct au1000_state *s = &au1000_state;
-       int             cnt, len = 0;
-
-       /* print out header */
-       len += sprintf(buf + len, "\n\t\tAU1000 Audio Debug\n\n");
-
-       // print out digital controller state
-       len += sprintf(buf + len, "AU1000 Audio Controller registers\n");
-       len += sprintf(buf + len, "---------------------------------\n");
-       len += sprintf (buf + len, "AC97C_CONFIG = %08x\n",
-                       au_readl(AC97C_CONFIG));
-       len += sprintf (buf + len, "AC97C_STATUS = %08x\n",
-                       au_readl(AC97C_STATUS));
-       len += sprintf (buf + len, "AC97C_CNTRL  = %08x\n",
-                       au_readl(AC97C_CNTRL));
-
-       /* print out CODEC state */
-       len += sprintf(buf + len, "\nAC97 CODEC registers\n");
-       len += sprintf(buf + len, "----------------------\n");
-       for (cnt = 0; cnt <= 0x7e; cnt += 2)
-               len += sprintf(buf + len, "reg %02x = %04x\n",
-                              cnt, rdcodec(&s->codec, cnt));
-
-       if (fpos >= len) {
-               *start = buf;
-               *eof = 1;
-               return 0;
-       }
-       *start = buf + fpos;
-       if ((len -= fpos) > length)
-               return length;
-       *eof = 1;
-       return len;
-
-}
-#endif /* AU1000_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("Au1000 Audio Driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __devinit au1000_probe(void)
-{
-       struct au1000_state *s = &au1000_state;
-       int             val;
-#ifdef AU1000_DEBUG
-       char            proc_str[80];
-#endif
-
-       memset(s, 0, sizeof(struct au1000_state));
-
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->codec.private_data = s;
-       s->codec.id = 0;
-       s->codec.codec_read = rdcodec;
-       s->codec.codec_write = wrcodec;
-       s->codec.codec_wait = waitcodec;
-
-       if (!request_mem_region(CPHYSADDR(AC97C_CONFIG),
-                           0x14, AU1000_MODULE_NAME)) {
-               err("AC'97 ports in use");
-               return -1;
-       }
-       // Allocate the DMA Channels
-       if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
-                                                  "audio DAC",
-                                                  dac_dma_interrupt,
-                                                  IRQF_DISABLED, s)) < 0) {
-               err("Can't get DAC DMA");
-               goto err_dma1;
-       }
-       if ((s->dma_adc.dmanr = request_au1000_dma(DMA_ID_AC97C_RX,
-                                                  "audio ADC",
-                                                  adc_dma_interrupt,
-                                                  IRQF_DISABLED, s)) < 0) {
-               err("Can't get ADC DMA");
-               goto err_dma2;
-       }
-
-       info("DAC: DMA%d/IRQ%d, ADC: DMA%d/IRQ%d",
-            s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
-            s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
-
-       // enable DMA coherency in read/write DMA channels
-       set_dma_mode(s->dma_dac.dmanr,
-                    get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
-       set_dma_mode(s->dma_adc.dmanr,
-                    get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
-
-       /* register devices */
-
-       if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
-               goto err_dev1;
-       if ((s->codec.dev_mixer =
-            register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
-               goto err_dev2;
-
-#ifdef AU1000_DEBUG
-       /* intialize the debug proc device */
-       s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
-                                      proc_au1000_dump, NULL);
-#endif /* AU1000_DEBUG */
-
-       // configure pins for AC'97
-       au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
-
-       // Assert reset for 10msec to the AC'97 controller, and enable clock
-       au_writel(AC97C_RS | AC97C_CE, AC97C_CNTRL);
-       au1000_delay(10);
-       au_writel(AC97C_CE, AC97C_CNTRL);
-       au1000_delay(10);       // wait for clock to stabilize
-
-       /* cold reset the AC'97 */
-       au_writel(AC97C_RESET, AC97C_CONFIG);
-       au1000_delay(10);
-       au_writel(0, AC97C_CONFIG);
-       /* need to delay around 500msec(bleech) to give
-          some CODECs enough time to wakeup */
-       au1000_delay(500);
-
-       /* warm reset the AC'97 to start the bitclk */
-       au_writel(AC97C_SG | AC97C_SYNC, AC97C_CONFIG);
-       udelay(100);
-       au_writel(0, AC97C_CONFIG);
-
-       /* codec init */
-       if (!ac97_probe_codec(&s->codec))
-               goto err_dev3;
-
-       s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
-       s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
-       info("AC'97 Base/Extended ID = %04x/%04x",
-            s->codec_base_caps, s->codec_ext_caps);
-
-       /*
-        * On the Pb1000, audio playback is on the AUX_OUT
-        * channel (which defaults to LNLVL_OUT in AC'97
-        * rev 2.2) so make sure this channel is listed
-        * as supported (soundcard.h calls this channel
-        * ALTPCM). ac97_codec.c does not handle detection
-        * of this channel correctly.
-        */
-       s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
-       /*
-        * Now set AUX_OUT's default volume.
-        */
-       val = 0x4343;
-       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
-                    (unsigned long) &val);
-       
-       if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
-               // codec does not support VRA
-               s->no_vra = 1;
-       } else if (!vra) {
-               // Boot option says disable VRA
-               u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-               wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-                       ac97_extstat & ~AC97_EXTSTAT_VRA);
-               s->no_vra = 1;
-       }
-       if (s->no_vra)
-               info("no VRA, interpolating and decimating");
-
-       /* set mic to be the recording source */
-       val = SOUND_MASK_MIC;
-       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
-                    (unsigned long) &val);
-
-#ifdef AU1000_DEBUG
-       sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
-               s->codec.id);
-       s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-                                            ac97_read_proc, &s->codec);
-#endif
-
-#ifdef CONFIG_MIPS_XXS1500
-       /* deassert eapd */
-       wrcodec(&s->codec, AC97_POWER_CONTROL,
-                       rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000);
-       /* mute a number of signals which seem to be causing problems
-        * if not muted.
-        */
-       wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000);
-       wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008);
-       wrcodec(&s->codec, AC97_MIC_VOL, 0x8008);
-       wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_CD_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_AUX_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808);
-       wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000);
-#endif
-
-       return 0;
-
- err_dev3:
-       unregister_sound_mixer(s->codec.dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       free_au1000_dma(s->dma_adc.dmanr);
- err_dma2:
-       free_au1000_dma(s->dma_dac.dmanr);
- err_dma1:
-       release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-       return -1;
-}
-
-static void au1000_remove(void)
-{
-       struct au1000_state *s = &au1000_state;
-
-       if (!s)
-               return;
-#ifdef AU1000_DEBUG
-       if (s->ps)
-               remove_proc_entry(AU1000_MODULE_NAME, NULL);
-#endif /* AU1000_DEBUG */
-       synchronize_irq();
-       free_au1000_dma(s->dma_adc.dmanr);
-       free_au1000_dma(s->dma_dac.dmanr);
-       release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->codec.dev_mixer);
-}
-
-static int __init init_au1000(void)
-{
-       info("stevel@mvista.com, built " __TIME__ " on " __DATE__);
-       return au1000_probe();
-}
-
-static void __exit cleanup_au1000(void)
-{
-       info("unloading");
-       au1000_remove();
-}
-
-module_init(init_au1000);
-module_exit(cleanup_au1000);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-static int __init au1000_setup(char *options)
-{
-       char           *this_opt;
-
-       if (!options || !*options)
-               return 0;
-
-       while ((this_opt = strsep(&options, ","))) {
-               if (!*this_opt)
-                       continue;
-               if (!strncmp(this_opt, "vra", 3)) {
-                       vra = 1;
-               }
-       }
-
-       return 1;
-}
-
-__setup("au1000_audio=", au1000_setup);
-
-#endif /* MODULE */
index 22dd63c368168e7bccccc5a3fcd7398e63da7450..89bd27a5e865adc5a8ff1870aabff63f889b6172 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/audio.c
+ * sound/oss/audio.c
  *
  * Device file manager for /dev/audio
  */
diff --git a/sound/oss/audio_syms.c b/sound/oss/audio_syms.c
deleted file mode 100644 (file)
index 5da217f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Exported symbols for audio driver.
- */
-
-#include <linux/module.h>
-
-char audio_syms_symbol;
-
-#include "sound_config.h"
-#include "sound_calls.h"
-
-EXPORT_SYMBOL(DMAbuf_start_dma);
-EXPORT_SYMBOL(DMAbuf_open_dma);
-EXPORT_SYMBOL(DMAbuf_close_dma);
-EXPORT_SYMBOL(DMAbuf_inputintr);
-EXPORT_SYMBOL(DMAbuf_outputintr);
diff --git a/sound/oss/awe_hw.h b/sound/oss/awe_hw.h
deleted file mode 100644 (file)
index 7e403ad..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * sound/awe_hw.h
- *
- * Access routines and definitions for the low level driver for the 
- * Creative AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AWE_HW_H_DEF
-#define AWE_HW_H_DEF
-
-/*
- * Emu-8000 control registers
- * name(channel)       reg, port
- */
-
-#define awe_cmd_idx(reg,ch)    (((reg)<< 5) | (ch))
-
-#define Data0    0             /* 0x620: doubleword r/w */
-#define Data1    1             /* 0xA20: doubleword r/w */
-#define Data2    2             /* 0xA22: word r/w */
-#define Data3    3             /* 0xE20: word r/w */
-#define Pointer  4             /* 0xE22 register pointer r/w */
-
-#define AWE_CPF(ch)    awe_cmd_idx(0,ch), Data0        /* DW: current pitch and fractional address */
-#define AWE_PTRX(ch)   awe_cmd_idx(1,ch), Data0        /* DW: pitch target and reverb send */
-#define AWE_CVCF(ch)   awe_cmd_idx(2,ch), Data0        /* DW: current volume and filter cutoff */
-#define AWE_VTFT(ch)   awe_cmd_idx(3,ch), Data0        /* DW: volume and filter cutoff targets */
-#define AWE_0080(ch)   awe_cmd_idx(4,ch), Data0        /* DW: ?? */
-#define AWE_00A0(ch)   awe_cmd_idx(5,ch), Data0        /* DW: ?? */
-#define AWE_PSST(ch)   awe_cmd_idx(6,ch), Data0        /* DW: pan send and loop start address */
-#define AWE_CSL(ch)    awe_cmd_idx(7,ch), Data0        /* DW: chorus send and loop end address */
-#define AWE_CCCA(ch)   awe_cmd_idx(0,ch), Data1        /* DW: Q, control bits, and current address */
-#define AWE_HWCF4      awe_cmd_idx(1,9),  Data1        /* DW: config dw 4 */
-#define AWE_HWCF5      awe_cmd_idx(1,10), Data1        /* DW: config dw 5 */
-#define AWE_HWCF6      awe_cmd_idx(1,13), Data1        /* DW: config dw 6 */
-#define AWE_HWCF7      awe_cmd_idx(1,14), Data1        /* DW: config dw 7? (not documented) */
-#define AWE_SMALR      awe_cmd_idx(1,20), Data1        /* DW: sound memory address for left read */
-#define AWE_SMARR      awe_cmd_idx(1,21), Data1        /* DW:    for right read */
-#define AWE_SMALW      awe_cmd_idx(1,22), Data1        /* DW: sound memory address for left write */
-#define AWE_SMARW      awe_cmd_idx(1,23), Data1        /* DW:    for right write */
-#define AWE_SMLD       awe_cmd_idx(1,26), Data1        /* W: sound memory left data */
-#define AWE_SMRD       awe_cmd_idx(1,26), Data2        /* W:    right data */
-#define AWE_WC         awe_cmd_idx(1,27), Data2        /* W: sample counter */
-#define AWE_WC_Cmd     awe_cmd_idx(1,27)
-#define AWE_WC_Port    Data2
-#define AWE_HWCF1      awe_cmd_idx(1,29), Data1        /* W: config w 1 */
-#define AWE_HWCF2      awe_cmd_idx(1,30), Data1        /* W: config w 2 */
-#define AWE_HWCF3      awe_cmd_idx(1,31), Data1        /* W: config w 3 */
-#define AWE_INIT1(ch)  awe_cmd_idx(2,ch), Data1        /* W: init array 1 */
-#define AWE_INIT2(ch)  awe_cmd_idx(2,ch), Data2        /* W: init array 2 */
-#define AWE_INIT3(ch)  awe_cmd_idx(3,ch), Data1        /* W: init array 3 */
-#define AWE_INIT4(ch)  awe_cmd_idx(3,ch), Data2        /* W: init array 4 */
-#define AWE_ENVVOL(ch) awe_cmd_idx(4,ch), Data1        /* W: volume envelope delay */
-#define AWE_DCYSUSV(ch)        awe_cmd_idx(5,ch), Data1        /* W: volume envelope sustain and decay */
-#define AWE_ENVVAL(ch) awe_cmd_idx(6,ch), Data1        /* W: modulation envelope delay */
-#define AWE_DCYSUS(ch) awe_cmd_idx(7,ch), Data1        /* W: modulation envelope sustain and decay */
-#define AWE_ATKHLDV(ch)        awe_cmd_idx(4,ch), Data2        /* W: volume envelope attack and hold */
-#define AWE_LFO1VAL(ch)        awe_cmd_idx(5,ch), Data2        /* W: LFO#1 Delay */
-#define AWE_ATKHLD(ch) awe_cmd_idx(6,ch), Data2        /* W: modulation envelope attack and hold */
-#define AWE_LFO2VAL(ch)        awe_cmd_idx(7,ch), Data2        /* W: LFO#2 Delay */
-#define AWE_IP(ch)     awe_cmd_idx(0,ch), Data3        /* W: initial pitch */
-#define AWE_IFATN(ch)  awe_cmd_idx(1,ch), Data3        /* W: initial filter cutoff and attenuation */
-#define AWE_PEFE(ch)   awe_cmd_idx(2,ch), Data3        /* W: pitch and filter envelope heights */
-#define AWE_FMMOD(ch)  awe_cmd_idx(3,ch), Data3        /* W: vibrato and filter modulation freq */
-#define AWE_TREMFRQ(ch)        awe_cmd_idx(4,ch), Data3        /* W: LFO#1 tremolo amount and freq */
-#define AWE_FM2FRQ2(ch)        awe_cmd_idx(5,ch), Data3        /* W: LFO#2 vibrato amount and freq */
-
-/* used during detection (returns ROM version?; not documented in ADIP) */
-#define AWE_U1         0xE0, Data3       /* (R)(W) used in initialization */
-#define AWE_U2(ch)     0xC0+(ch), Data3  /* (W)(W) used in init envelope  */
-
-
-#define AWE_MAX_VOICES         32
-#define AWE_NORMAL_VOICES      30      /*30&31 are reserved for DRAM refresh*/
-
-#define AWE_MAX_CHANNELS       32      /* max midi channels (must >= voices) */
-#define AWE_MAX_LAYERS AWE_MAX_VOICES  /* maximum number of multiple layers */
-
-#define AWE_DRAM_OFFSET                0x200000
-#define AWE_MAX_DRAM_SIZE      (28 * 1024)     /* 28 MB is max onboard memory */
-
-#endif
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
deleted file mode 100644 (file)
index d1a0eb2..0000000
+++ /dev/null
@@ -1,6149 +0,0 @@
-/*
- * sound/awe_wave.c
- *
- * The low level driver for the AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Changelog:
- * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
- * - detection code rewrite
- */
-
-#include <linux/awe_voice.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/pnp.h>
-
-#include "sound_config.h"
-
-#include "awe_wave.h"
-#include "awe_hw.h"
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-#include "tuning.h"
-#include <linux/ultrasound.h>
-#endif
-
-/*
- * debug message
- */
-
-#ifdef AWE_DEBUG_ON
-#define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
-#define ERRMSG(XXX)    {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
-#define FATALERR(XXX)  XXX
-#else
-#define DEBUG(LVL,XXX) /**/
-#define ERRMSG(XXX)    XXX
-#define FATALERR(XXX)  XXX
-#endif
-
-/*
- * bank and voice record
- */
-
-typedef struct _sf_list sf_list;
-typedef struct _awe_voice_list awe_voice_list;
-typedef struct _awe_sample_list awe_sample_list;
-
-/* soundfont record */
-struct _sf_list {
-       unsigned short sf_id;   /* id number */
-       unsigned short type;    /* lock & shared flags */
-       int num_info;           /* current info table index */
-       int num_sample;         /* current sample table index */
-       int mem_ptr;            /* current word byte pointer */
-       awe_voice_list *infos, *last_infos;     /* instruments */
-       awe_sample_list *samples, *last_samples;        /* samples */
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       sf_list *shared;        /* shared list */
-       unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
-#endif
-       sf_list *next, *prev;
-};
-
-/* instrument list */
-struct _awe_voice_list {
-       awe_voice_info v;       /* instrument information */
-       sf_list *holder;        /* parent sf_list of this record */
-       unsigned char bank, instr;      /* preset number information */
-       char type, disabled;    /* type=normal/mapped, disabled=boolean */
-       awe_voice_list *next;   /* linked list with same sf_id */
-       awe_voice_list *next_instr;     /* instrument list */
-       awe_voice_list *next_bank;      /* hash table list */
-};
-
-/* voice list type */
-#define V_ST_NORMAL    0
-#define V_ST_MAPPED    1
-
-/* sample list */
-struct _awe_sample_list {
-       awe_sample_info v;      /* sample information */
-       sf_list *holder;        /* parent sf_list of this record */
-       awe_sample_list *next;  /* linked list with same sf_id */
-};
-
-/* sample and information table */
-static int current_sf_id;      /* current number of fonts */
-static int locked_sf_id;       /* locked position */
-static sf_list *sfhead, *sftail;       /* linked-lists */
-
-#define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
-#define awe_free_info() (sftail ? sftail->num_info : 0)
-#define awe_free_sample() (sftail ? sftail->num_sample : 0)
-
-#define AWE_MAX_PRESETS                256
-#define AWE_DEFAULT_PRESET     0
-#define AWE_DEFAULT_BANK       0
-#define AWE_DEFAULT_DRUM       0
-#define AWE_DRUM_BANK          128
-
-#define MAX_LAYERS     AWE_MAX_VOICES
-
-/* preset table index */
-static awe_voice_list *preset_table[AWE_MAX_PRESETS];
-
-/*
- * voice table
- */
-
-/* effects table */
-typedef        struct FX_Rec { /* channel effects */
-       unsigned char flags[AWE_FX_END];
-       short val[AWE_FX_END];
-} FX_Rec;
-
-
-/* channel parameters */
-typedef struct _awe_chan_info {
-       int channel;            /* channel number */
-       int bank;               /* current tone bank */
-       int instr;              /* current program */
-       int bender;             /* midi pitchbend (-8192 - 8192) */
-       int bender_range;       /* midi bender range (x100) */
-       int panning;            /* panning (0-127) */
-       int main_vol;           /* channel volume (0-127) */
-       int expression_vol;     /* midi expression (0-127) */
-       int chan_press;         /* channel pressure */
-       int sustained;          /* sustain status in MIDI */
-       FX_Rec fx;              /* effects */
-       FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
-} awe_chan_info;
-
-/* voice parameters */
-typedef struct _voice_info {
-       int state;
-#define AWE_ST_OFF             (1<<0)  /* no sound */
-#define AWE_ST_ON              (1<<1)  /* playing */
-#define AWE_ST_STANDBY         (1<<2)  /* stand by for playing */
-#define AWE_ST_SUSTAINED       (1<<3)  /* sustained */
-#define AWE_ST_MARK            (1<<4)  /* marked for allocation */
-#define AWE_ST_DRAM            (1<<5)  /* DRAM read/write */
-#define AWE_ST_FM              (1<<6)  /* reserved for FM */
-#define AWE_ST_RELEASED                (1<<7)  /* released */
-
-       int ch;                 /* midi channel */
-       int key;                /* internal key for search */
-       int layer;              /* layer number (for channel mode only) */
-       int time;               /* allocated time */
-       awe_chan_info   *cinfo; /* channel info */
-
-       int note;               /* midi key (0-127) */
-       int velocity;           /* midi velocity (0-127) */
-       int sostenuto;          /* sostenuto on/off */
-       awe_voice_info *sample; /* assigned voice */
-
-       /* EMU8000 parameters */
-       int apitch;             /* pitch parameter */
-       int avol;               /* volume parameter */
-       int apan;               /* panning parameter */
-       int acutoff;            /* cutoff parameter */
-       short aaux;             /* aux word */
-} voice_info;
-
-/* voice information */
-static voice_info voices[AWE_MAX_VOICES];
-
-#define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
-#define IS_NO_EFFECT(v)        (voices[v].state != AWE_ST_ON)
-#define IS_PLAYING(v)  (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
-#define IS_EMPTY(v)    (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
-
-
-/* MIDI channel effects information (for hw control) */
-static awe_chan_info channels[AWE_MAX_CHANNELS];
-
-
-/*
- * global variables
- */
-
-#ifndef AWE_DEFAULT_BASE_ADDR
-#define AWE_DEFAULT_BASE_ADDR  0       /* autodetect */
-#endif
-
-#ifndef AWE_DEFAULT_MEM_SIZE
-#define AWE_DEFAULT_MEM_SIZE   -1      /* autodetect */
-#endif
-
-static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
-static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
-#ifdef CONFIG_PNP
-static int isapnp = -1;
-#else
-static int isapnp;
-#endif
-
-MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
-MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "base i/o port of Emu8000");
-module_param(memsize, int, 0);
-MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
-module_param(isapnp, bool, 0);
-MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
-
-/* DRAM start offset */
-static int awe_mem_start = AWE_DRAM_OFFSET;
-
-/* maximum channels for playing */
-static int awe_max_voices = AWE_MAX_VOICES;
-
-static int patch_opened;               /* sample already loaded? */
-
-static char atten_relative = FALSE;
-static short atten_offset;
-
-static int awe_present = FALSE;                /* awe device present? */
-static int awe_busy = FALSE;           /* awe device opened? */
-
-static int my_dev = -1;
-
-#define DEFAULT_DRUM_FLAGS     ((1 << 9) | (1 << 25))
-#define IS_DRUM_CHANNEL(c)     (drum_flags & (1 << (c)))
-#define DRUM_CHANNEL_ON(c)     (drum_flags |= (1 << (c)))
-#define DRUM_CHANNEL_OFF(c)    (drum_flags &= ~(1 << (c)))
-static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
-
-static int playing_mode = AWE_PLAY_INDIRECT;
-#define SINGLE_LAYER_MODE()    (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
-#define MULTI_LAYER_MODE()     (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
-
-static int current_alloc_time;         /* voice allocation index for channel mode */
-
-static struct synth_info awe_info = {
-       "AWE32 Synth",          /* name */
-       0,                      /* device */
-       SYNTH_TYPE_SAMPLE,      /* synth_type */
-       SAMPLE_TYPE_AWE32,      /* synth_subtype */
-       0,                      /* perc_mode (obsolete) */
-       AWE_MAX_VOICES,         /* nr_voices */
-       0,                      /* nr_drums (obsolete) */
-       400                     /* instr_bank_size */
-};
-
-
-static struct voice_alloc_info *voice_alloc;   /* set at initialization */
-
-
-/*
- * function prototypes
- */
-
-static int awe_request_region(void);
-static void awe_release_region(void);
-
-static void awe_reset_samples(void);
-/* emu8000 chip i/o access */
-static void setup_ports(int p1, int p2, int p3);
-static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
-static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
-static unsigned short awe_peek(unsigned short cmd, unsigned short port);
-static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
-static void awe_wait(unsigned short delay);
-
-/* initialize emu8000 chip */
-static void awe_initialize(void);
-
-/* set voice parameters */
-static void awe_init_ctrl_parms(int init_all);
-static void awe_init_voice_info(awe_voice_info *vp);
-static void awe_init_voice_parm(awe_voice_parm *pp);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int freq_to_note(int freq);
-static int calc_rate_offset(int Hz);
-/*static int calc_parm_delay(int msec);*/
-static int calc_parm_hold(int msec);
-static int calc_parm_attack(int msec);
-static int calc_parm_decay(int msec);
-static int calc_parm_search(int msec, short *table);
-#endif /* gus compat */
-
-/* turn on/off note */
-static void awe_note_on(int voice);
-static void awe_note_off(int voice);
-static void awe_terminate(int voice);
-static void awe_exclusive_off(int voice);
-static void awe_note_off_all(int do_sustain);
-
-/* calculate voice parameters */
-typedef void (*fx_affect_func)(int voice, int forced);
-static void awe_set_pitch(int voice, int forced);
-static void awe_set_voice_pitch(int voice, int forced);
-static void awe_set_volume(int voice, int forced);
-static void awe_set_voice_vol(int voice, int forced);
-static void awe_set_pan(int voice, int forced);
-static void awe_fx_fmmod(int voice, int forced);
-static void awe_fx_tremfrq(int voice, int forced);
-static void awe_fx_fm2frq2(int voice, int forced);
-static void awe_fx_filterQ(int voice, int forced);
-static void awe_calc_pitch(int voice);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_calc_pitch_from_freq(int voice, int freq);
-#endif
-static void awe_calc_volume(int voice);
-static void awe_update_volume(void);
-static void awe_change_master_volume(short val);
-static void awe_voice_init(int voice, int init_all);
-static void awe_channel_init(int ch, int init_all);
-static void awe_fx_init(int ch);
-static void awe_send_effect(int voice, int layer, int type, int val);
-static void awe_modwheel_change(int voice, int value);
-
-/* sequencer interface */
-static int awe_open(int dev, int mode);
-static void awe_close(int dev);
-static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
-static int awe_kill_note(int dev, int voice, int note, int velocity);
-static int awe_start_note(int dev, int v, int note_num, int volume);
-static int awe_set_instr(int dev, int voice, int instr_no);
-static int awe_set_instr_2(int dev, int voice, int instr_no);
-static void awe_reset(int dev);
-static void awe_hw_control(int dev, unsigned char *event);
-static int awe_load_patch(int dev, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag);
-static void awe_aftertouch(int dev, int voice, int pressure);
-static void awe_controller(int dev, int voice, int ctrl_num, int value);
-static void awe_panning(int dev, int voice, int value);
-static void awe_volume_method(int dev, int mode);
-static void awe_bender(int dev, int voice, int value);
-static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
-static void awe_setup_voice(int dev, int voice, int chn);
-
-#define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
-
-/* hardware controls */
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
-#endif
-static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
-static void awe_voice_change(int voice, fx_affect_func func);
-static void awe_sostenuto_on(int voice, int forced);
-static void awe_sustain_off(int voice, int forced);
-static void awe_terminate_and_init(int voice, int forced);
-
-/* voice search */
-static int awe_search_key(int bank, int preset, int note);
-static awe_voice_list *awe_search_instr(int bank, int preset, int note);
-static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
-static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
-static void awe_alloc_one_voice(int voice, int note, int velocity);
-static int awe_clear_voice(void);
-
-/* load / remove patches */
-static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag);
-#endif
-/*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/
-static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
-static sf_list *check_patch_opened(int type, char *name);
-static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
-static int awe_create_sf(int type, char *name);
-static void awe_free_sf(sf_list *sf);
-static void add_sf_info(sf_list *sf, awe_voice_list *rec);
-static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
-static void add_info_list(awe_voice_list *rec);
-static void awe_remove_samples(int sf_id);
-static void rebuild_preset_list(void);
-static short awe_set_sample(awe_voice_list *rec);
-static awe_sample_list *search_sample_index(sf_list *sf, int sample);
-
-static int is_identical_holder(sf_list *sf1, sf_list *sf2);
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-static int is_identical_name(unsigned char *name, sf_list *p);
-static int is_shared_sf(unsigned char *name);
-static int info_duplicated(sf_list *sf, awe_voice_list *rec);
-#endif /* allow sharing */
-
-/* lowlevel functions */
-static void awe_init_audio(void);
-static void awe_init_dma(void);
-static void awe_init_array(void);
-static void awe_send_array(unsigned short *data);
-static void awe_tweak_voice(int voice);
-static void awe_tweak(void);
-static void awe_init_fm(void);
-static int awe_open_dram_for_write(int offset, int channels);
-static void awe_open_dram_for_check(void);
-static void awe_close_dram(void);
-/*static void awe_write_dram(unsigned short c);*/
-static int awe_detect_base(int addr);
-static int awe_detect(void);
-static void awe_check_dram(void);
-static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_chorus_mode(int mode);
-static void awe_update_chorus_mode(void);
-static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_reverb_mode(int mode);
-static void awe_update_reverb_mode(void);
-static void awe_equalizer(int bass, int treble);
-static void awe_update_equalizer(void);
-
-#ifdef CONFIG_AWE32_MIXER
-static void attach_mixer(void);
-static void unload_mixer(void);
-#endif
-
-#ifdef CONFIG_AWE32_MIDIEMU
-static void attach_midiemu(void);
-static void unload_midiemu(void);
-#endif
-
-#define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
-
-/*
- * control parameters
- */
-
-
-#ifdef AWE_USE_NEW_VOLUME_CALC
-#define DEF_VOLUME_CALC        TRUE
-#else
-#define DEF_VOLUME_CALC        FALSE
-#endif /* new volume */
-
-#define DEF_ZERO_ATTEN         32      /* 12dB below */
-#define DEF_MOD_SENSE          18
-#define DEF_CHORUS_MODE                2
-#define DEF_REVERB_MODE                4
-#define DEF_BASS_LEVEL         5
-#define DEF_TREBLE_LEVEL       9
-
-static struct CtrlParmsDef {
-       int value;
-       int init_each_time;
-       void (*update)(void);
-} ctrl_parms[AWE_MD_END] = {
-       {0,0, NULL}, {0,0, NULL}, /* <-- not used */
-       {AWE_VERSION_NUMBER, FALSE, NULL},
-       {TRUE, FALSE, NULL}, /* exclusive */
-       {TRUE, FALSE, NULL}, /* realpan */
-       {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
-       {FALSE, TRUE, NULL}, /* keep effect */
-       {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
-       {FALSE, FALSE, NULL}, /* chn_prior */
-       {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
-       {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
-       {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
-       {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
-       {FALSE, FALSE, NULL}, /* toggle_drum_bank */
-       {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
-       {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
-       {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
-       {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
-       {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
-       {0, FALSE, NULL},       /* debug mode */
-       {FALSE, FALSE, NULL}, /* pan exchange */
-};
-
-static int ctrls[AWE_MD_END];
-
-
-/*
- * synth operation table
- */
-
-static struct synth_operations awe_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "EMU8K",
-       .info           = &awe_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_AWE32,
-       .open           = awe_open,
-       .close          = awe_close,
-       .ioctl          = awe_ioctl,
-       .kill_note      = awe_kill_note,
-       .start_note     = awe_start_note,
-       .set_instr      = awe_set_instr_2,
-       .reset          = awe_reset,
-       .hw_control     = awe_hw_control,
-       .load_patch     = awe_load_patch,
-       .aftertouch     = awe_aftertouch,
-       .controller     = awe_controller,
-       .panning        = awe_panning,
-       .volume_method  = awe_volume_method,
-       .bender         = awe_bender,
-       .alloc_voice    = awe_alloc,
-       .setup_voice    = awe_setup_voice
-};
-
-static void free_tables(void)
-{
-       if (sftail) {
-               sf_list *p, *prev;
-               for (p = sftail; p; p = prev) {
-                       prev = p->prev;
-                       awe_free_sf(p);
-               }
-       }
-       sfhead = sftail = NULL;
-}
-
-/*
- * clear sample tables 
- */
-
-static void
-awe_reset_samples(void)
-{
-       /* free all bank tables */
-       memset(preset_table, 0, sizeof(preset_table));
-       free_tables();
-
-       current_sf_id = 0;
-       locked_sf_id = 0;
-       patch_opened = 0;
-}
-
-
-/*
- * EMU register access
- */
-
-/* select a given AWE32 pointer */
-static int awe_ports[5];
-static int port_setuped = FALSE;
-static int awe_cur_cmd = -1;
-#define awe_set_cmd(cmd) \
-if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
-
-/* write 16bit data */
-static void
-awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
-{
-       awe_set_cmd(cmd);
-       outw(data, awe_ports[port]);
-}
-
-/* write 32bit data */
-static void
-awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
-{
-       unsigned short addr = awe_ports[port];
-       awe_set_cmd(cmd);
-       outw(data, addr);               /* write lower 16 bits */
-       outw(data >> 16, addr + 2);     /* write higher 16 bits */
-}
-
-/* read 16bit data */
-static unsigned short
-awe_peek(unsigned short cmd, unsigned short port)
-{
-       unsigned short k;
-       awe_set_cmd(cmd);
-       k = inw(awe_ports[port]);
-       return k;
-}
-
-/* read 32bit data */
-static unsigned int
-awe_peek_dw(unsigned short cmd, unsigned short port)
-{
-       unsigned int k1, k2;
-       unsigned short addr = awe_ports[port];
-       awe_set_cmd(cmd);
-       k1 = inw(addr);
-       k2 = inw(addr + 2);
-       k1 |= k2 << 16;
-       return k1;
-}
-
-/* wait delay number of AWE32 44100Hz clocks */
-#ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
-static void
-awe_wait(unsigned short delay)
-{
-       unsigned short clock, target;
-       unsigned short port = awe_ports[AWE_WC_Port];
-       int counter;
-  
-       /* sample counter */
-       awe_set_cmd(AWE_WC_Cmd);
-       clock = (unsigned short)inw(port);
-       target = clock + delay;
-       counter = 0;
-       if (target < clock) {
-               for (; (unsigned short)inw(port) > target; counter++)
-                       if (counter > 65536)
-                               break;
-       }
-       for (; (unsigned short)inw(port) < target; counter++)
-               if (counter > 65536)
-                       break;
-}
-#else
-
-static void awe_wait(unsigned short delay)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
-}
-/*
-static void awe_wait(unsigned short delay)
-{
-       udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
-}
-*/
-#endif /* wait by loop */
-
-/* write a word data */
-#define awe_write_dram(c)      awe_poke(AWE_SMLD, c)
-
-/*
- * AWE32 voice parameters
- */
-
-/* initialize voice_info record */
-static void
-awe_init_voice_info(awe_voice_info *vp)
-{
-       vp->sample = 0;
-       vp->rate_offset = 0;
-
-       vp->start = 0;
-       vp->end = 0;
-       vp->loopstart = 0;
-       vp->loopend = 0;
-       vp->mode = 0;
-       vp->root = 60;
-       vp->tune = 0;
-       vp->low = 0;
-       vp->high = 127;
-       vp->vellow = 0;
-       vp->velhigh = 127;
-
-       vp->fixkey = -1;
-       vp->fixvel = -1;
-       vp->fixpan = -1;
-       vp->pan = -1;
-
-       vp->exclusiveClass = 0;
-       vp->amplitude = 127;
-       vp->attenuation = 0;
-       vp->scaleTuning = 100;
-
-       awe_init_voice_parm(&vp->parm);
-}
-
-/* initialize voice_parm record:
- * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
- * Vibrato and Tremolo effects are zero.
- * Cutoff is maximum.
- * Chorus and Reverb effects are zero.
- */
-static void
-awe_init_voice_parm(awe_voice_parm *pp)
-{
-       pp->moddelay = 0x8000;
-       pp->modatkhld = 0x7f7f;
-       pp->moddcysus = 0x7f7f;
-       pp->modrelease = 0x807f;
-       pp->modkeyhold = 0;
-       pp->modkeydecay = 0;
-
-       pp->voldelay = 0x8000;
-       pp->volatkhld = 0x7f7f;
-       pp->voldcysus = 0x7f7f;
-       pp->volrelease = 0x807f;
-       pp->volkeyhold = 0;
-       pp->volkeydecay = 0;
-
-       pp->lfo1delay = 0x8000;
-       pp->lfo2delay = 0x8000;
-       pp->pefe = 0;
-
-       pp->fmmod = 0;
-       pp->tremfrq = 0;
-       pp->fm2frq2 = 0;
-
-       pp->cutoff = 0xff;
-       pp->filterQ = 0;
-
-       pp->chorus = 0;
-       pp->reverb = 0;
-}      
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* convert frequency mHz to abstract cents (= midi key * 100) */
-static int
-freq_to_note(int mHz)
-{
-       /* abscents = log(mHz/8176) / log(2) * 1200 */
-       unsigned int max_val = (unsigned int)0xffffffff / 10000;
-       int i, times;
-       unsigned int base;
-       unsigned int freq;
-       int note, tune;
-
-       if (mHz == 0)
-               return 0;
-       if (mHz < 0)
-               return 12799; /* maximum */
-
-       freq = mHz;
-       note = 0;
-       for (base = 8176 * 2; freq >= base; base *= 2) {
-               note += 12;
-               if (note >= 128) /* over maximum */
-                       return 12799;
-       }
-       base /= 2;
-
-       /* to avoid overflow... */
-       times = 10000;
-       while (freq > max_val) {
-               max_val *= 10;
-               times /= 10;
-               base /= 10;
-       }
-
-       freq = freq * times / base;
-       for (i = 0; i < 12; i++) {
-               if (freq < semitone_tuning[i+1])
-                       break;
-               note++;
-       }
-
-       tune = 0;
-       freq = freq * 10000 / semitone_tuning[i];
-       for (i = 0; i < 100; i++) {
-               if (freq < cent_tuning[i+1])
-                       break;
-               tune++;
-       }
-
-       return note * 100 + tune;
-}
-
-
-/* convert Hz to AWE32 rate offset:
- * sample pitch offset for the specified sample rate
- * rate=44100 is no offset, each 4096 is 1 octave (twice).
- * eg, when rate is 22050, this offset becomes -4096.
- */
-static int
-calc_rate_offset(int Hz)
-{
-       /* offset = log(Hz / 44100) / log(2) * 4096 */
-       int freq, base, i;
-
-       /* maybe smaller than max (44100Hz) */
-       if (Hz <= 0 || Hz >= 44100) return 0;
-
-       base = 0;
-       for (freq = Hz * 2; freq < 44100; freq *= 2)
-               base++;
-       base *= 1200;
-
-       freq = 44100 * 10000 / (freq/2);
-       for (i = 0; i < 12; i++) {
-               if (freq < semitone_tuning[i+1])
-                       break;
-               base += 100;
-       }
-       freq = freq * 10000 / semitone_tuning[i];
-       for (i = 0; i < 100; i++) {
-               if (freq < cent_tuning[i+1])
-                       break;
-               base++;
-       }
-       return -base * 4096 / 1200;
-}
-
-
-/*
- * convert envelope time parameter to AWE32 raw parameter
- */
-
-/* attack & decay/release time table (msec) */
-static short attack_time_tbl[128] = {
-32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
-707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
-361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
-180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
-90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
-45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
-22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
-11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
-};
-
-static short decay_time_tbl[128] = {
-32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
-2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
-1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
-691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
-345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
-172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
-86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
-43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
-};
-
-#define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
-
-/* delay time = 0x8000 - msec/92 */
-static int
-calc_parm_hold(int msec)
-{
-       int val = (0x7f * 92 - msec) / 92;
-       if (val < 1) val = 1;
-       if (val > 127) val = 127;
-       return val;
-}
-
-/* attack time: search from time table */
-static int
-calc_parm_attack(int msec)
-{
-       return calc_parm_search(msec, attack_time_tbl);
-}
-
-/* decay/release time: search from time table */
-static int
-calc_parm_decay(int msec)
-{
-       return calc_parm_search(msec, decay_time_tbl);
-}
-
-/* search an index for specified time from given time table */
-static int
-calc_parm_search(int msec, short *table)
-{
-       int left = 1, right = 127, mid;
-       while (left < right) {
-               mid = (left + right) / 2;
-               if (msec < (int)table[mid])
-                       left = mid + 1;
-               else
-                       right = mid;
-       }
-       return left;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * effects table
- */
-
-/* set an effect value */
-#define FX_FLAG_OFF    0
-#define FX_FLAG_SET    1
-#define FX_FLAG_ADD    2
-
-#define FX_SET(rec,type,value) \
-       ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
-#define FX_ADD(rec,type,value) \
-       ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
-#define FX_UNSET(rec,type) \
-       ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
-
-/* check the effect value is set */
-#define FX_ON(rec,type)        ((rec)->flags[type])
-
-#define PARM_BYTE      0
-#define PARM_WORD      1
-#define PARM_SIGN      2
-
-static struct PARM_DEFS {
-       int type;       /* byte or word */
-       int low, high;  /* value range */
-       fx_affect_func realtime;        /* realtime paramater change */
-} parm_defs[] = {
-       {PARM_WORD, 0, 0x8000, NULL},   /* env1 delay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 attack */
-       {PARM_BYTE, 0, 0x7e, NULL},     /* env1 hold */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 decay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 release */
-       {PARM_BYTE, 0, 0x7f, NULL},     /* env1 sustain */
-       {PARM_BYTE, 0, 0xff, NULL},     /* env1 pitch */
-       {PARM_BYTE, 0, 0xff, NULL},     /* env1 cutoff */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* env2 delay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 attack */
-       {PARM_BYTE, 0, 0x7e, NULL},     /* env2 hold */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 decay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 release */
-       {PARM_BYTE, 0, 0x7f, NULL},     /* env2 sustain */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* lfo1 delay */
-       {PARM_BYTE, 0, 0xff, awe_fx_tremfrq},   /* lfo1 freq */
-       {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
-       {PARM_SIGN, -128, 127, awe_fx_fmmod},   /* lfo1 pitch */
-       {PARM_BYTE, 0, 0xff, awe_fx_fmmod},     /* lfo1 cutoff */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* lfo2 delay */
-       {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2},   /* lfo2 freq */
-       {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
-
-       {PARM_WORD, 0, 0xffff, awe_set_voice_pitch},    /* initial pitch */
-       {PARM_BYTE, 0, 0xff, NULL},     /* chorus */
-       {PARM_BYTE, 0, 0xff, NULL},     /* reverb */
-       {PARM_BYTE, 0, 0xff, awe_set_volume},   /* initial cutoff */
-       {PARM_BYTE, 0, 15, awe_fx_filterQ},     /* initial resonance */
-
-       {PARM_WORD, 0, 0xffff, NULL},   /* sample start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* loop start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* loop end */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse sample start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse loop start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse loop end */
-       {PARM_BYTE, 0, 0xff, awe_set_volume},   /* initial attenuation */
-};
-
-
-static unsigned char
-FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
-{
-       int effect = 0;
-       int on = 0;
-       if (lay && (on = FX_ON(lay, type)) != 0)
-               effect = lay->val[type];
-       if (!on && (on = FX_ON(rec, type)) != 0)
-               effect = rec->val[type];
-       if (on == FX_FLAG_ADD) {
-               if (parm_defs[type].type == PARM_SIGN) {
-                       if (value > 0x7f)
-                               effect += (int)value - 0x100;
-                       else
-                               effect += (int)value;
-               } else {
-                       effect += (int)value;
-               }
-       }
-       if (on) {
-               if (effect < parm_defs[type].low)
-                       effect = parm_defs[type].low;
-               else if (effect > parm_defs[type].high)
-                       effect = parm_defs[type].high;
-               return (unsigned char)effect;
-       }
-       return value;
-}
-
-/* get word effect value */
-static unsigned short
-FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
-{
-       int effect = 0;
-       int on = 0;
-       if (lay && (on = FX_ON(lay, type)) != 0)
-               effect = lay->val[type];
-       if (!on && (on = FX_ON(rec, type)) != 0)
-               effect = rec->val[type];
-       if (on == FX_FLAG_ADD)
-               effect += (int)value;
-       if (on) {
-               if (effect < parm_defs[type].low)
-                       effect = parm_defs[type].low;
-               else if (effect > parm_defs[type].high)
-                       effect = parm_defs[type].high;
-               return (unsigned short)effect;
-       }
-       return value;
-}
-
-/* get word (upper=type1/lower=type2) effect value */
-static unsigned short
-FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
-{
-       unsigned short tmp;
-       tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
-       tmp <<= 8;
-       tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
-       return tmp;
-}
-
-/* address offset */
-static int
-FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
-{
-       int addr = 0;
-       if (lay && FX_ON(lay, hi))
-               addr = (short)lay->val[hi];
-       else if (FX_ON(rec, hi))
-               addr = (short)rec->val[hi];
-       addr = addr << 15;
-       if (lay && FX_ON(lay, lo))
-               addr += (short)lay->val[lo];
-       else if (FX_ON(rec, lo))
-               addr += (short)rec->val[lo];
-       if (!(mode & AWE_SAMPLE_8BITS))
-               addr /= 2;
-       return addr;
-}
-
-
-/*
- * turn on/off sample
- */
-
-/* table for volume target calculation */
-static unsigned short voltarget[16] = { 
-   0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
-   0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
-};
-
-static void
-awe_note_on(int voice)
-{
-       unsigned int temp;
-       int addr;
-       int vtarget, ftarget, ptarget, pitch;
-       awe_voice_info *vp;
-       awe_voice_parm_block *parm;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       /* A voice sample must assigned before calling */
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       parm = (awe_voice_parm_block*)&vp->parm;
-
-       /* channel to be silent and idle */
-       awe_poke(AWE_DCYSUSV(voice), 0x0080);
-       awe_poke(AWE_VTFT(voice), 0x0000FFFF);
-       awe_poke(AWE_CVCF(voice), 0x0000FFFF);
-       awe_poke(AWE_PTRX(voice), 0);
-       awe_poke(AWE_CPF(voice), 0);
-
-       /* set pitch offset */
-       awe_set_pitch(voice, TRUE);
-
-       /* modulation & volume envelope */
-       if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
-               awe_poke(AWE_ENVVAL(voice), 0xBFFF);
-               pitch = (parm->env1pit<<4) + voices[voice].apitch;
-               if (pitch > 0xffff) pitch = 0xffff;
-               /* calculate filter target */
-               ftarget = parm->cutoff + parm->env1fc;
-               limitvalue(ftarget, 0, 255);
-               ftarget <<= 8;
-       } else {
-               awe_poke(AWE_ENVVAL(voice),
-                        FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
-               ftarget = parm->cutoff;
-               ftarget <<= 8;
-               pitch = voices[voice].apitch;
-       }
-
-       /* calcualte pitch target */
-       if (pitch != 0xffff) {
-               ptarget = 1 << (pitch >> 12);
-               if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
-               if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
-               if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
-               ptarget += (ptarget>>1);
-               if (ptarget > 0xffff) ptarget = 0xffff;
-
-       } else ptarget = 0xffff;
-       if (parm->modatk >= 0x80)
-               awe_poke(AWE_ATKHLD(voice),
-                        FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
-       else
-               awe_poke(AWE_ATKHLD(voice),
-                        FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
-                                vp->parm.modatkhld));
-       awe_poke(AWE_DCYSUS(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
-                         vp->parm.moddcysus));
-
-       if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
-               awe_poke(AWE_ENVVOL(voice), 0xBFFF);
-               vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
-       } else {
-               awe_poke(AWE_ENVVOL(voice),
-                        FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
-               vtarget = 0;
-       }
-       if (parm->volatk >= 0x80)
-               awe_poke(AWE_ATKHLDV(voice),
-                        FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
-       else
-               awe_poke(AWE_ATKHLDV(voice),
-                        FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
-                        vp->parm.volatkhld));
-       /* decay/sustain parameter for volume envelope must be set at last */
-
-       /* cutoff and volume */
-       awe_set_volume(voice, TRUE);
-
-       /* modulation envelope heights */
-       awe_poke(AWE_PEFE(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
-                        vp->parm.pefe));
-
-       /* lfo1/2 delay */
-       awe_poke(AWE_LFO1VAL(voice),
-                FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
-       awe_poke(AWE_LFO2VAL(voice),
-                FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
-
-       /* lfo1 pitch & cutoff shift */
-       awe_fx_fmmod(voice, TRUE);
-       /* lfo1 volume & freq */
-       awe_fx_tremfrq(voice, TRUE);
-       /* lfo2 pitch & freq */
-       awe_fx_fm2frq2(voice, TRUE);
-       /* pan & loop start */
-       awe_set_pan(voice, TRUE);
-
-       /* chorus & loop end (chorus 8bit, MSB) */
-       addr = vp->loopend - 1;
-       addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
-                         AWE_FX_COARSE_LOOP_END, vp->mode);
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
-       temp = (temp <<24) | (unsigned int)addr;
-       awe_poke_dw(AWE_CSL(voice), temp);
-       DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
-
-       /* Q & current address (Q 4bit value, MSB) */
-       addr = vp->start - 1;
-       addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
-                         AWE_FX_COARSE_SAMPLE_START, vp->mode);
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
-       temp = (temp<<28) | (unsigned int)addr;
-       awe_poke_dw(AWE_CCCA(voice), temp);
-       DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
-
-       /* clear unknown registers */
-       awe_poke_dw(AWE_00A0(voice), 0);
-       awe_poke_dw(AWE_0080(voice), 0);
-
-       /* reset volume */
-       awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
-       awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
-
-       /* set reverb */
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
-       temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
-       awe_poke_dw(AWE_PTRX(voice), temp);
-       awe_poke_dw(AWE_CPF(voice), ptarget << 16);
-       /* turn on envelope */
-       awe_poke(AWE_DCYSUSV(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
-                         vp->parm.voldcysus));
-
-       voices[voice].state = AWE_ST_ON;
-
-       /* clear voice position for the next note on this channel */
-       if (SINGLE_LAYER_MODE()) {
-               FX_UNSET(fx, AWE_FX_SAMPLE_START);
-               FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
-       }
-}
-
-
-/* turn off the voice */
-static void
-awe_note_off(int voice)
-{
-       awe_voice_info *vp;
-       unsigned short tmp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if ((vp = voices[voice].sample) == NULL) {
-               voices[voice].state = AWE_ST_OFF;
-               return;
-       }
-
-       tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
-                              (unsigned char)vp->parm.modrelease);
-       awe_poke(AWE_DCYSUS(voice), tmp);
-       tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
-                              (unsigned char)vp->parm.volrelease);
-       awe_poke(AWE_DCYSUSV(voice), tmp);
-       voices[voice].state = AWE_ST_RELEASED;
-}
-
-/* force to terminate the voice (no releasing echo) */
-static void
-awe_terminate(int voice)
-{
-       awe_poke(AWE_DCYSUSV(voice), 0x807F);
-       awe_tweak_voice(voice);
-       voices[voice].state = AWE_ST_OFF;
-}
-
-/* turn off other voices with the same exclusive class (for drums) */
-static void
-awe_exclusive_off(int voice)
-{
-       int i, exclass;
-
-       if (voices[voice].sample == NULL)
-               return;
-       if ((exclass = voices[voice].sample->exclusiveClass) == 0)
-               return; /* not exclusive */
-
-       /* turn off voices with the same class */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (i != voice && IS_PLAYING(i) &&
-                   voices[i].sample && voices[i].ch == voices[voice].ch &&
-                   voices[i].sample->exclusiveClass == exclass) {
-                       DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
-                       awe_terminate(i);
-                       awe_voice_init(i, TRUE);
-               }
-       }
-}
-
-
-/*
- * change the parameters of an audible voice
- */
-
-/* change pitch */
-static void
-awe_set_pitch(int voice, int forced)
-{
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       awe_poke(AWE_IP(voice), voices[voice].apitch);
-       DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
-}
-
-/* calculate & change pitch */
-static void
-awe_set_voice_pitch(int voice, int forced)
-{
-       awe_calc_pitch(voice);
-       awe_set_pitch(voice, forced);
-}
-
-/* change volume & cutoff */
-static void
-awe_set_volume(int voice, int forced)
-{
-       awe_voice_info *vp;
-       unsigned short tmp2;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (!IS_PLAYING(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
-                      (unsigned char)voices[voice].acutoff);
-       tmp2 = (tmp2 << 8);
-       tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
-                       (unsigned char)voices[voice].avol);
-       awe_poke(AWE_IFATN(voice), tmp2);
-}
-
-/* calculate & change volume */
-static void
-awe_set_voice_vol(int voice, int forced)
-{
-       if (IS_EMPTY(voice))
-               return;
-       awe_calc_volume(voice);
-       awe_set_volume(voice, forced);
-}
-
-
-/* change pan; this could make a click noise.. */
-static void
-awe_set_pan(int voice, int forced)
-{
-       unsigned int temp;
-       int addr;
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
-       if (vp->fixpan > 0)     /* 0-127 */
-               temp = 255 - (int)vp->fixpan * 2;
-       else {
-               int pos = 0;
-               if (vp->pan >= 0) /* 0-127 */
-                       pos = (int)vp->pan * 2 - 128;
-               pos += voices[voice].cinfo->panning; /* -128 - 127 */
-               temp = 127 - pos;
-       }
-       limitvalue(temp, 0, 255);
-       if (ctrls[AWE_MD_PAN_EXCHANGE]) {
-               temp = 255 - temp;
-       }
-       if (forced || temp != voices[voice].apan) {
-               voices[voice].apan = temp;
-               if (temp == 0)
-                       voices[voice].aaux = 0xff;
-               else
-                       voices[voice].aaux = (-temp) & 0xff;
-               addr = vp->loopstart - 1;
-               addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
-                                 AWE_FX_COARSE_LOOP_START, vp->mode);
-               temp = (temp<<24) | (unsigned int)addr;
-               awe_poke_dw(AWE_PSST(voice), temp);
-               DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
-       }
-}
-
-/* effects change during playing */
-static void
-awe_fx_fmmod(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_FMMOD(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
-                        vp->parm.fmmod));
-}
-
-/* set tremolo (lfo1) volume & frequency */
-static void
-awe_fx_tremfrq(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_TREMFRQ(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
-                        vp->parm.tremfrq));
-}
-
-/* set lfo2 pitch & frequency */
-static void
-awe_fx_fm2frq2(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_FM2FRQ2(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
-                        vp->parm.fm2frq2));
-}
-
-
-/* Q & current address (Q 4bit value, MSB) */
-static void
-awe_fx_filterQ(int voice, int forced)
-{
-       unsigned int addr;
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
-       addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
-       awe_poke_dw(AWE_CCCA(voice), addr);
-}
-
-/*
- * calculate pitch offset
- *
- * 0xE000 is no pitch offset at 44100Hz sample.
- * Every 4096 is one octave.
- */
-
-static void
-awe_calc_pitch(int voice)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       awe_chan_info *cp = voices[voice].cinfo;
-       int offset;
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-                       return;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-
-       /* calculate offset */
-       if (ap->fixkey >= 0) {
-               DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
-               offset = (ap->fixkey - ap->root) * 4096 / 12;
-       } else {
-               DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
-               offset = (vp->note - ap->root) * 4096 / 12;
-               DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
-       }
-       offset = (offset * ap->scaleTuning) / 100;
-       DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
-       offset += ap->tune * 4096 / 1200;
-       DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
-       if (cp->bender != 0) {
-               DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
-               /* (819200: 1 semitone) ==> (4096: 12 semitones) */
-               offset += cp->bender * cp->bender_range / 2400;
-       }
-
-       /* add initial pitch correction */
-       if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
-               offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
-       else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
-               offset += cp->fx.val[AWE_FX_INIT_PITCH];
-
-       /* 0xe000: root pitch */
-       vp->apitch = 0xe000 + ap->rate_offset + offset;
-       DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
-       if (vp->apitch > 0xffff)
-               vp->apitch = 0xffff;
-       if (vp->apitch < 0)
-               vp->apitch = 0;
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-/* calculate MIDI key and semitone from the specified frequency */
-static void
-awe_calc_pitch_from_freq(int voice, int freq)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       int offset;
-       int note;
-
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-               return;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-       note = freq_to_note(freq);
-       offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
-       offset = (offset * ap->scaleTuning) / 100;
-       if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
-               offset += fx_lay->val[AWE_FX_INIT_PITCH];
-       else if (FX_ON(fx, AWE_FX_INIT_PITCH))
-               offset += fx->val[AWE_FX_INIT_PITCH];
-       vp->apitch = 0xe000 + ap->rate_offset + offset;
-       if (vp->apitch > 0xffff)
-               vp->apitch = 0xffff;
-       if (vp->apitch < 0)
-               vp->apitch = 0;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * calculate volume attenuation
- *
- * Voice volume is controlled by volume attenuation parameter.
- * So volume becomes maximum when avol is 0 (no attenuation), and
- * minimum when 255 (-96dB or silence).
- */
-
-static int vol_table[128] = {
-       255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
-       47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
-       31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
-       22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
-       15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
-       10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
-       6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
-       2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
-};
-
-/* tables for volume->attenuation calculation */
-static unsigned char voltab1[128] = {
-   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
-   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
-   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
-   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
-   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
-   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
-   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
-   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char voltab2[128] = {
-   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
-   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
-   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
-   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
-   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
-   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
-   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
-   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
-   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char expressiontab[128] = {
-   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
-   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
-   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
-   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
-   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
-   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
-   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
-   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
-   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
-   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static void
-awe_calc_volume(int voice)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       awe_chan_info *cp = voices[voice].cinfo;
-       int vol;
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-               return;
-
-       ap = vp->sample;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-       
-       if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
-               int main_vol = cp->main_vol * ap->amplitude / 127;
-               limitvalue(vp->velocity, 0, 127);
-               limitvalue(main_vol, 0, 127);
-               limitvalue(cp->expression_vol, 0, 127);
-
-               vol = voltab1[main_vol] + voltab2[vp->velocity];
-               vol = (vol * 8) / 3;
-               vol += ap->attenuation;
-               if (cp->expression_vol < 127)
-                       vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
-               vol += atten_offset;
-               if (atten_relative)
-                       vol += ctrls[AWE_MD_ZERO_ATTEN];
-               limitvalue(vol, 0, 255);
-               vp->avol = vol;
-               
-       } else {
-               /* 0 - 127 */
-               vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
-               vol = vol * ap->amplitude / 127;
-
-               if (vol < 0) vol = 0;
-               if (vol > 127) vol = 127;
-
-               /* calc to attenuation */
-               vol = vol_table[vol];
-               vol += (int)ap->attenuation;
-               vol += atten_offset;
-               if (atten_relative)
-                       vol += ctrls[AWE_MD_ZERO_ATTEN];
-               if (vol > 255) vol = 255;
-
-               vp->avol = vol;
-       }
-       if (cp->bank !=  AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
-               int atten;
-               if (vp->velocity < 70) atten = 70;
-               else atten = vp->velocity;
-               vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
-       } else {
-               vp->acutoff = ap->parm.cutoff;
-       }
-       DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
-}
-
-/* change master volume */
-static void
-awe_change_master_volume(short val)
-{
-       limitvalue(val, 0, 127);
-       atten_offset = vol_table[val];
-       atten_relative = TRUE;
-       awe_update_volume();
-}
-
-/* update volumes of all available channels */
-static void awe_update_volume(void)
-{
-       int i;
-       for (i = 0; i < awe_max_voices; i++)
-               awe_set_voice_vol(i, TRUE);
-}
-
-/* set sostenuto on */
-static void awe_sostenuto_on(int voice, int forced)
-{
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       voices[voice].sostenuto = 127;
-}
-
-
-/* drop sustain */
-static void awe_sustain_off(int voice, int forced)
-{
-       if (voices[voice].state == AWE_ST_SUSTAINED) {
-               awe_note_off(voice);
-               awe_fx_init(voices[voice].ch);
-               awe_voice_init(voice, FALSE);
-       }
-}
-
-
-/* terminate and initialize voice */
-static void awe_terminate_and_init(int voice, int forced)
-{
-       awe_terminate(voice);
-       awe_fx_init(voices[voice].ch);
-       awe_voice_init(voice, TRUE);
-}
-
-
-/*
- * synth operation routines
- */
-
-#define AWE_VOICE_KEY(v)       (0x8000 | (v))
-#define AWE_CHAN_KEY(c,n)      (((c) << 8) | ((n) + 1))
-#define KEY_CHAN_MATCH(key,c)  (((key) >> 8) == (c))
-
-/* initialize the voice */
-static void
-awe_voice_init(int voice, int init_all)
-{
-       voice_info *vp = &voices[voice];
-
-       /* reset voice search key */
-       if (playing_mode == AWE_PLAY_DIRECT)
-               vp->key = AWE_VOICE_KEY(voice);
-       else
-               vp->key = 0;
-
-       /* clear voice mapping */
-       voice_alloc->map[voice] = 0;
-
-       /* touch the timing flag */
-       vp->time = current_alloc_time;
-
-       /* initialize other parameters if necessary */
-       if (init_all) {
-               vp->note = -1;
-               vp->velocity = 0;
-               vp->sostenuto = 0;
-
-               vp->sample = NULL;
-               vp->cinfo = &channels[voice];
-               vp->ch = voice;
-               vp->state = AWE_ST_OFF;
-
-               /* emu8000 parameters */
-               vp->apitch = 0;
-               vp->avol = 255;
-               vp->apan = -1;
-       }
-}
-
-/* clear effects */
-static void awe_fx_init(int ch)
-{
-       if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
-               memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
-               memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
-       }
-}
-
-/* initialize channel info */
-static void awe_channel_init(int ch, int init_all)
-{
-       awe_chan_info *cp = &channels[ch];
-       cp->channel = ch;
-       if (init_all) {
-               cp->panning = 0; /* zero center */
-               cp->bender_range = 200; /* sense * 100 */
-               cp->main_vol = 127;
-               if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
-                       cp->instr = ctrls[AWE_MD_DEF_DRUM];
-                       cp->bank = AWE_DRUM_BANK;
-               } else {
-                       cp->instr = ctrls[AWE_MD_DEF_PRESET];
-                       cp->bank = ctrls[AWE_MD_DEF_BANK];
-               }
-       }
-
-       cp->bender = 0; /* zero tune skew */
-       cp->expression_vol = 127;
-       cp->chan_press = 0;
-       cp->sustained = 0;
-
-       if (! ctrls[AWE_MD_KEEP_EFFECT]) {
-               memset(&cp->fx, 0, sizeof(cp->fx));
-               memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
-       }
-}
-
-
-/* change the voice parameters; voice = channel */
-static void awe_voice_change(int voice, fx_affect_func func)
-{
-       int i; 
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-               func(voice, FALSE);
-               break;
-       case AWE_PLAY_INDIRECT:
-               for (i = 0; i < awe_max_voices; i++)
-                       if (voices[i].key == AWE_VOICE_KEY(voice))
-                               func(i, FALSE);
-               break;
-       default:
-               for (i = 0; i < awe_max_voices; i++)
-                       if (KEY_CHAN_MATCH(voices[i].key, voice))
-                               func(i, FALSE);
-               break;
-       }
-}
-
-
-/*
- * device open / close
- */
-
-/* open device:
- *   reset status of all voices, and clear sample position flag
- */
-static int
-awe_open(int dev, int mode)
-{
-       if (awe_busy)
-               return -EBUSY;
-
-       awe_busy = TRUE;
-
-       /* set default mode */
-       awe_init_ctrl_parms(FALSE);
-       atten_relative = TRUE;
-       atten_offset = 0;
-       drum_flags = DEFAULT_DRUM_FLAGS;
-       playing_mode = AWE_PLAY_INDIRECT;
-
-       /* reset voices & channels */
-       awe_reset(dev);
-
-       patch_opened = 0;
-
-       return 0;
-}
-
-
-/* close device:
- *   reset all voices again (terminate sounds)
- */
-static void
-awe_close(int dev)
-{
-       awe_reset(dev);
-       awe_busy = FALSE;
-}
-
-
-/* set miscellaneous mode parameters
- */
-static void
-awe_init_ctrl_parms(int init_all)
-{
-       int i;
-       for (i = 0; i < AWE_MD_END; i++) {
-               if (init_all || ctrl_parms[i].init_each_time)
-                       ctrls[i] = ctrl_parms[i].value;
-       }
-}
-
-
-/* sequencer I/O control:
- */
-static int
-awe_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       switch (cmd) {
-       case SNDCTL_SYNTH_INFO:
-               if (playing_mode == AWE_PLAY_DIRECT)
-                       awe_info.nr_voices = awe_max_voices;
-               else
-                       awe_info.nr_voices = AWE_MAX_CHANNELS;
-               if (copy_to_user(arg, &awe_info, sizeof(awe_info)))
-                       return -EFAULT;
-               return 0;
-               break;
-
-       case SNDCTL_SEQ_RESETSAMPLES:
-               awe_reset(dev);
-               awe_reset_samples();
-               return 0;
-               break;
-
-       case SNDCTL_SEQ_PERCMODE:
-               /* what's this? */
-               return 0;
-               break;
-
-       case SNDCTL_SYNTH_MEMAVL:
-               return memsize - awe_free_mem_ptr() * 2;
-               break;
-
-       default:
-               printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
-               return -EINVAL;
-               break;
-       }
-}
-
-
-static int voice_in_range(int voice)
-{
-       if (playing_mode == AWE_PLAY_DIRECT) {
-               if (voice < 0 || voice >= awe_max_voices)
-                       return FALSE;
-       } else {
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static void release_voice(int voice, int do_sustain)
-{
-       if (IS_NO_SOUND(voice))
-               return;
-       if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
-                           voices[voice].sostenuto == 127))
-               voices[voice].state = AWE_ST_SUSTAINED;
-       else {
-               awe_note_off(voice);
-               awe_fx_init(voices[voice].ch);
-               awe_voice_init(voice, FALSE);
-       }
-}
-
-/* release all notes */
-static void awe_note_off_all(int do_sustain)
-{
-       int i;
-       for (i = 0; i < awe_max_voices; i++)
-               release_voice(i, do_sustain);
-}
-
-/* kill a voice:
- *   not terminate, just release the voice.
- */
-static int
-awe_kill_note(int dev, int voice, int note, int velocity)
-{
-       int i, v2, key;
-
-       DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
-       if (! voice_in_range(voice))
-               return -EINVAL;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               key = AWE_VOICE_KEY(voice);
-               break;
-
-       case AWE_PLAY_MULTI2:
-               v2 = voice_alloc->map[voice] >> 8;
-               voice_alloc->map[voice] = 0;
-               voice = v2;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-               /* continue to below */
-       default:
-               key = AWE_CHAN_KEY(voice, note);
-               break;
-       }
-
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key)
-                       release_voice(i, TRUE);
-       }
-       return 0;
-}
-
-
-static void start_or_volume_change(int voice, int velocity)
-{
-       voices[voice].velocity = velocity;
-       awe_calc_volume(voice);
-       if (voices[voice].state == AWE_ST_STANDBY)
-               awe_note_on(voice);
-       else if (voices[voice].state == AWE_ST_ON)
-               awe_set_volume(voice, FALSE);
-}
-
-static void set_and_start_voice(int voice, int state)
-{
-       /* calculate pitch & volume parameters */
-       voices[voice].state = state;
-       awe_calc_pitch(voice);
-       awe_calc_volume(voice);
-       if (state == AWE_ST_ON)
-               awe_note_on(voice);
-}
-
-/* start a voice:
- *   if note is 255, identical with aftertouch function.
- *   Otherwise, start a voice with specified not and volume.
- */
-static int
-awe_start_note(int dev, int voice, int note, int velocity)
-{
-       int i, key, state, volonly;
-
-       DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
-       if (! voice_in_range(voice))
-               return -EINVAL;
-           
-       if (velocity == 0)
-               state = AWE_ST_STANDBY; /* stand by for playing */
-       else
-               state = AWE_ST_ON;      /* really play */
-       volonly = FALSE;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               key = AWE_VOICE_KEY(voice);
-               if (note == 255)
-                       volonly = TRUE;
-               break;
-
-       case AWE_PLAY_MULTI2:
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-               /* continue to below */
-       default:
-               if (note >= 128) { /* key volume mode */
-                       note -= 128;
-                       volonly = TRUE;
-               }
-               key = AWE_CHAN_KEY(voice, note);
-               break;
-       }
-
-       /* dynamic volume change */
-       if (volonly) {
-               for (i = 0; i < awe_max_voices; i++) {
-                       if (voices[i].key == key)
-                               start_or_volume_change(i, velocity);
-               }
-               return 0;
-       }
-
-       /* if the same note still playing, stop it */
-       if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
-               for (i = 0; i < awe_max_voices; i++)
-                       if (voices[i].key == key) {
-                               if (voices[i].state == AWE_ST_ON) {
-                                       awe_note_off(i);
-                                       awe_voice_init(i, FALSE);
-                               } else if (voices[i].state == AWE_ST_STANDBY)
-                                       awe_voice_init(i, TRUE);
-                       }
-       }
-
-       /* allocate voices */
-       if (playing_mode == AWE_PLAY_DIRECT)
-               awe_alloc_one_voice(voice, note, velocity);
-       else
-               awe_alloc_multi_voices(voice, note, velocity, key);
-
-       /* turn off other voices exlusively (for drums) */
-       for (i = 0; i < awe_max_voices; i++)
-               if (voices[i].key == key)
-                       awe_exclusive_off(i);
-
-       /* set up pitch and volume parameters */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
-                       set_and_start_voice(i, state);
-       }
-
-       return 0;
-}
-
-
-/* calculate hash key */
-static int
-awe_search_key(int bank, int preset, int note)
-{
-       unsigned int key;
-
-#if 1 /* new hash table */
-       if (bank == AWE_DRUM_BANK)
-               key = preset + note + 128;
-       else
-               key = bank + preset;
-#else
-       key = preset;
-#endif
-       key %= AWE_MAX_PRESETS;
-
-       return (int)key;
-}
-
-
-/* search instrument from hash table */
-static awe_voice_list *
-awe_search_instr(int bank, int preset, int note)
-{
-       awe_voice_list *p;
-       int key, key2;
-
-       key = awe_search_key(bank, preset, note);
-       for (p = preset_table[key]; p; p = p->next_bank) {
-               if (p->instr == preset && p->bank == bank)
-                       return p;
-       }
-       key2 = awe_search_key(bank, preset, 0); /* search default */
-       if (key == key2)
-               return NULL;
-       for (p = preset_table[key2]; p; p = p->next_bank) {
-               if (p->instr == preset && p->bank == bank)
-                       return p;
-       }
-       return NULL;
-}
-
-
-/* assign the instrument to a voice */
-static int
-awe_set_instr_2(int dev, int voice, int instr_no)
-{
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-       }
-       return awe_set_instr(dev, voice, instr_no);
-}
-
-/* assign the instrument to a channel; voice is the channel number */
-static int
-awe_set_instr(int dev, int voice, int instr_no)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return -EINVAL;
-
-       if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
-               return -EINVAL;
-
-       cinfo = &channels[voice];
-       cinfo->instr = instr_no;
-       DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
-
-       return 0;
-}
-
-
-/* reset all voices; terminate sounds and initialize parameters */
-static void
-awe_reset(int dev)
-{
-       int i;
-       current_alloc_time = 0;
-       /* don't turn off voice 31 and 32.  they are used also for FM voices */
-       for (i = 0; i < awe_max_voices; i++) {
-               awe_terminate(i);
-               awe_voice_init(i, TRUE);
-       }
-       for (i = 0; i < AWE_MAX_CHANNELS; i++)
-               awe_channel_init(i, TRUE);
-       for (i = 0; i < 16; i++) {
-               awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
-               awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
-       }
-       awe_init_fm();
-       awe_tweak();
-}
-
-
-/* hardware specific control:
- *   GUS specific and AWE32 specific controls are available.
- */
-static void
-awe_hw_control(int dev, unsigned char *event)
-{
-       int cmd = event[2];
-       if (cmd & _AWE_MODE_FLAG)
-               awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-       else
-               awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#endif
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* GUS compatible controls */
-static void
-awe_hw_gus_control(int dev, int cmd, unsigned char *event)
-{
-       int voice, i, key;
-       unsigned short p1;
-       short p2;
-       int plong;
-
-       if (MULTI_LAYER_MODE())
-               return;
-       if (cmd == _GUS_NUMVOICES)
-               return;
-
-       voice = event[3];
-       if (! voice_in_range(voice))
-               return;
-
-       p1 = *(unsigned short *) &event[4];
-       p2 = *(short *) &event[6];
-       plong = *(int*) &event[4];
-
-       switch (cmd) {
-       case _GUS_VOICESAMPLE:
-               awe_set_instr(dev, voice, p1);
-               return;
-
-       case _GUS_VOICEBALA:
-               /* 0 to 15 --> -128 to 127 */
-               awe_panning(dev, voice, ((int)p1 << 4) - 128);
-               return;
-
-       case _GUS_VOICEVOL:
-       case _GUS_VOICEVOL2:
-               /* not supported yet */
-               return;
-
-       case _GUS_RAMPRANGE:
-       case _GUS_RAMPRATE:
-       case _GUS_RAMPMODE:
-       case _GUS_RAMPON:
-       case _GUS_RAMPOFF:
-               /* volume ramping not supported */
-               return;
-
-       case _GUS_VOLUME_SCALE:
-               return;
-
-       case _GUS_VOICE_POS:
-               FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
-                      (short)(plong & 0x7fff));
-               FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
-                      (plong >> 15) & 0xffff);
-               return;
-       }
-
-       key = AWE_VOICE_KEY(voice);
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key) {
-                       switch (cmd) {
-                       case _GUS_VOICEON:
-                               awe_note_on(i);
-                               break;
-
-                       case _GUS_VOICEOFF:
-                               awe_terminate(i);
-                               awe_fx_init(voices[i].ch);
-                               awe_voice_init(i, TRUE);
-                               break;
-
-                       case _GUS_VOICEFADE:
-                               awe_note_off(i);
-                               awe_fx_init(voices[i].ch);
-                               awe_voice_init(i, FALSE);
-                               break;
-
-                       case _GUS_VOICEFREQ:
-                               awe_calc_pitch_from_freq(i, plong);
-                               break;
-                       }
-               }
-       }
-}
-
-#endif /* gus_compat */
-
-
-/* AWE32 specific controls */
-static void
-awe_hw_awe_control(int dev, int cmd, unsigned char *event)
-{
-       int voice;
-       unsigned short p1;
-       short p2;
-       int i;
-
-       voice = event[3];
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       p1 = *(unsigned short *) &event[4];
-       p2 = *(short *) &event[6];
-
-       switch (cmd) {
-       case _AWE_DEBUG_MODE:
-               ctrls[AWE_MD_DEBUG_MODE] = p1;
-               printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
-               break;
-       case _AWE_REVERB_MODE:
-               ctrls[AWE_MD_REVERB_MODE] = p1;
-               awe_update_reverb_mode();
-               break;
-
-       case _AWE_CHORUS_MODE:
-               ctrls[AWE_MD_CHORUS_MODE] = p1;
-               awe_update_chorus_mode();
-               break;
-                     
-       case _AWE_REMOVE_LAST_SAMPLES:
-               DEBUG(0,printk("AWE32: remove last samples\n"));
-               awe_reset(0);
-               if (locked_sf_id > 0)
-                       awe_remove_samples(locked_sf_id);
-               break;
-
-       case _AWE_INITIALIZE_CHIP:
-               awe_initialize();
-               break;
-
-       case _AWE_SEND_EFFECT:
-               i = -1;
-               if (p1 >= 0x100) {
-                       i = (p1 >> 8);
-                       if (i < 0 || i >= MAX_LAYERS)
-                               break;
-               }
-               awe_send_effect(voice, i, p1, p2);
-               break;
-
-       case _AWE_RESET_CHANNEL:
-               awe_channel_init(voice, !p1);
-               break;
-               
-       case _AWE_TERMINATE_ALL:
-               awe_reset(0);
-               break;
-
-       case _AWE_TERMINATE_CHANNEL:
-               awe_voice_change(voice, awe_terminate_and_init);
-               break;
-
-       case _AWE_RELEASE_ALL:
-               awe_note_off_all(FALSE);
-               break;
-       case _AWE_NOTEOFF_ALL:
-               awe_note_off_all(TRUE);
-               break;
-
-       case _AWE_INITIAL_VOLUME:
-               DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
-               atten_relative = (char)p2;
-               atten_offset = (short)p1;
-               awe_update_volume();
-               break;
-
-       case _AWE_CHN_PRESSURE:
-               channels[voice].chan_press = p1;
-               awe_modwheel_change(voice, p1);
-               break;
-
-       case _AWE_CHANNEL_MODE:
-               DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
-               playing_mode = p1;
-               awe_reset(0);
-               break;
-
-       case _AWE_DRUM_CHANNELS:
-               DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
-               drum_flags = *(unsigned int*)&event[4];
-               break;
-
-       case _AWE_MISC_MODE:
-               DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
-               if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
-                       ctrls[p1] = p2;
-                       if (ctrl_parms[p1].update)
-                               ctrl_parms[p1].update();
-               }
-               break;
-
-       case _AWE_EQUALIZER:
-               ctrls[AWE_MD_BASS_LEVEL] = p1;
-               ctrls[AWE_MD_TREBLE_LEVEL] = p2;
-               awe_update_equalizer();
-               break;
-
-       default:
-               DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
-               break;
-       }
-}
-
-
-/* change effects */
-static void
-awe_send_effect(int voice, int layer, int type, int val)
-{
-       awe_chan_info *cinfo;
-       FX_Rec *fx;
-       int mode;
-
-       cinfo = &channels[voice];
-       if (layer >= 0 && layer < MAX_LAYERS)
-               fx = &cinfo->fx_layer[layer];
-       else
-               fx = &cinfo->fx;
-
-       if (type & 0x40)
-               mode = FX_FLAG_OFF;
-       else if (type & 0x80)
-               mode = FX_FLAG_ADD;
-       else
-               mode = FX_FLAG_SET;
-       type &= 0x3f;
-
-       if (type >= 0 && type < AWE_FX_END) {
-               DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
-               if (mode == FX_FLAG_SET)
-                       FX_SET(fx, type, val);
-               else if (mode == FX_FLAG_ADD)
-                       FX_ADD(fx, type, val);
-               else
-                       FX_UNSET(fx, type);
-               if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
-                       DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
-                       awe_voice_change(voice, parm_defs[type].realtime);
-               }
-       }
-}
-
-
-/* change modulation wheel; voice is already mapped on multi2 mode */
-static void
-awe_modwheel_change(int voice, int value)
-{
-       int i;
-       awe_chan_info *cinfo;
-
-       cinfo = &channels[voice];
-       i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
-       FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
-       awe_voice_change(voice, awe_fx_fmmod);
-       FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
-       awe_voice_change(voice, awe_fx_fm2frq2);
-}
-
-
-/* voice pressure change */
-static void
-awe_aftertouch(int dev, int voice, int pressure)
-{
-       int note;
-
-       DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
-       if (! voice_in_range(voice))
-               return;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               awe_start_note(dev, voice, 255, pressure);
-               break;
-       case AWE_PLAY_MULTI2:
-               note = (voice_alloc->map[voice] & 0xff) - 1;
-               awe_key_pressure(dev, voice, note + 0x80, pressure);
-               break;
-       }
-}
-
-
-/* voice control change */
-static void
-awe_controller(int dev, int voice, int ctrl_num, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       cinfo = &channels[voice];
-
-       switch (ctrl_num) {
-       case CTL_BANK_SELECT: /* MIDI control #0 */
-               DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
-               if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
-                   !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
-                       break;
-               if (value < 0 || value > 255)
-                       break;
-               cinfo->bank = value;
-               if (cinfo->bank == AWE_DRUM_BANK)
-                       DRUM_CHANNEL_ON(cinfo->channel);
-               else
-                       DRUM_CHANNEL_OFF(cinfo->channel);
-               awe_set_instr(dev, voice, cinfo->instr);
-               break;
-
-       case CTL_MODWHEEL: /* MIDI control #1 */
-               DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
-               awe_modwheel_change(voice, value);
-               break;
-
-       case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
-               DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
-               /* zero centered */
-               cinfo->bender = value;
-               awe_voice_change(voice, awe_set_voice_pitch);
-               break;
-
-       case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
-               /* value = sense x 100 */
-               cinfo->bender_range = value;
-               /* no audible pitch change yet.. */
-               break;
-
-       case CTL_EXPRESSION: /* MIDI control #11 */
-               if (SINGLE_LAYER_MODE())
-                       value /= 128;
-       case CTRL_EXPRESSION: /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
-               /* 0 - 127 */
-               cinfo->expression_vol = value;
-               awe_voice_change(voice, awe_set_voice_vol);
-               break;
-
-       case CTL_PAN:   /* MIDI control #10 */
-               DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
-               /* (0-127) -> signed 8bit */
-               cinfo->panning = value * 2 - 128;
-               if (ctrls[AWE_MD_REALTIME_PAN])
-                       awe_voice_change(voice, awe_set_pan);
-               break;
-
-       case CTL_MAIN_VOLUME:   /* MIDI control #7 */
-               if (SINGLE_LAYER_MODE())
-                       value = (value * 100) / 16383;
-       case CTRL_MAIN_VOLUME:  /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
-               /* 0 - 127 */
-               cinfo->main_vol = value;
-               awe_voice_change(voice, awe_set_voice_vol);
-               break;
-
-       case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
-               DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
-               FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
-               break;
-
-       case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
-               DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
-               FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
-               break;
-
-       case 120:  /* all sounds off */
-               awe_note_off_all(FALSE);
-               break;
-       case 123:  /* all notes off */
-               awe_note_off_all(TRUE);
-               break;
-
-       case CTL_SUSTAIN: /* MIDI control #64 */
-               cinfo->sustained = value;
-               if (value != 127)
-                       awe_voice_change(voice, awe_sustain_off);
-               break;
-
-       case CTL_SOSTENUTO: /* MIDI control #66 */
-               if (value == 127)
-                       awe_voice_change(voice, awe_sostenuto_on);
-               else
-                       awe_voice_change(voice, awe_sustain_off);
-               break;
-
-       default:
-               DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
-                          voice, ctrl_num, value));
-               break;
-       }
-}
-
-
-/* voice pan change (value = -128 - 127) */
-static void
-awe_panning(int dev, int voice, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       cinfo = &channels[voice];
-       cinfo->panning = value;
-       DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
-       if (ctrls[AWE_MD_REALTIME_PAN])
-               awe_voice_change(voice, awe_set_pan);
-}
-
-
-/* volume mode change */
-static void
-awe_volume_method(int dev, int mode)
-{
-       /* not impremented */
-       DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
-}
-
-
-/* pitch wheel change: 0-16384 */
-static void
-awe_bender(int dev, int voice, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       /* convert to zero centered value */
-       cinfo = &channels[voice];
-       cinfo->bender = value - 8192;
-       DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
-       awe_voice_change(voice, awe_set_voice_pitch);
-}
-
-
-/*
- * load a sound patch:
- *   three types of patches are accepted: AWE, GUS, and SYSEX.
- */
-
-static int
-awe_load_patch(int dev, int format, const char __user *addr,
-              int offs, int count, int pmgr_flag)
-{
-       awe_patch_info patch;
-       int rc = 0;
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-       if (format == GUS_PATCH) {
-               return awe_load_guspatch(addr, offs, count, pmgr_flag);
-       } else
-#endif
-       if (format == SYSEX_PATCH) {
-               /* no system exclusive message supported yet */
-               return 0;
-       } else if (format != AWE_PATCH) {
-               printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
-               return -EINVAL;
-       }
-       
-       if (count < AWE_PATCH_INFO_SIZE) {
-               printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(((char*)&patch) + offs, addr + offs, 
-                          AWE_PATCH_INFO_SIZE - offs))
-               return -EFAULT;
-
-       count -= AWE_PATCH_INFO_SIZE;
-       if (count < patch.len) {
-               printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
-                      count, patch.len);
-               return -EINVAL;
-       }
-       
-       switch (patch.type) {
-       case AWE_LOAD_INFO:
-               rc = awe_load_info(&patch, addr, count);
-               break;
-       case AWE_LOAD_DATA:
-               rc = awe_load_data(&patch, addr, count);
-               break;
-       case AWE_OPEN_PATCH:
-               rc = awe_open_patch(&patch, addr, count);
-               break;
-       case AWE_CLOSE_PATCH:
-               rc = awe_close_patch(&patch, addr, count);
-               break;
-       case AWE_UNLOAD_PATCH:
-               rc = awe_unload_patch(&patch, addr, count);
-               break;
-       case AWE_REPLACE_DATA:
-               rc = awe_replace_data(&patch, addr, count);
-               break;
-       case AWE_MAP_PRESET:
-               rc = awe_load_map(&patch, addr, count);
-               break;
-       /* case AWE_PROBE_INFO:
-               rc = awe_probe_info(&patch, addr, count);
-               break;*/
-       case AWE_PROBE_DATA:
-               rc = awe_probe_data(&patch, addr, count);
-               break;
-       case AWE_REMOVE_INFO:
-               rc = awe_remove_info(&patch, addr, count);
-               break;
-       case AWE_LOAD_CHORUS_FX:
-               rc = awe_load_chorus_fx(&patch, addr, count);
-               break;
-       case AWE_LOAD_REVERB_FX:
-               rc = awe_load_reverb_fx(&patch, addr, count);
-               break;
-
-       default:
-               printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
-                      patch.type);
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
-
-
-/* create an sf list record */
-static int
-awe_create_sf(int type, char *name)
-{
-       sf_list *rec;
-
-       /* terminate sounds */
-       awe_reset(0);
-       rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
-       if (rec == NULL)
-               return 1; /* no memory */
-       rec->sf_id = current_sf_id + 1;
-       rec->type = type;
-       if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
-               locked_sf_id = current_sf_id + 1;
-       rec->num_info = awe_free_info();
-       rec->num_sample = awe_free_sample();
-       rec->mem_ptr = awe_free_mem_ptr();
-       rec->infos = rec->last_infos = NULL;
-       rec->samples = rec->last_samples = NULL;
-
-       /* add to linked-list */
-       rec->next = NULL;
-       rec->prev = sftail;
-       if (sftail)
-               sftail->next = rec;
-       else
-               sfhead = rec;
-       sftail = rec;
-       current_sf_id++;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       rec->shared = NULL;
-       if (name)
-               memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
-       else
-               strcpy(rec->name, "*TEMPORARY*");
-       if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
-               /* is the current font really a shared font? */
-               if (is_shared_sf(rec->name)) {
-                       /* check if the shared font is already installed */
-                       sf_list *p;
-                       for (p = rec->prev; p; p = p->prev) {
-                               if (is_identical_name(rec->name, p)) {
-                                       rec->shared = p;
-                                       break;
-                               }
-                       }
-               }
-       }
-#endif /* allow sharing */
-
-       return 0;
-}
-
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-
-/* check if the given name is a valid shared name */
-#define ASC_TO_KEY(c) ((c) - 'A' + 1)
-static int is_shared_sf(unsigned char *name)
-{
-       static unsigned char id_head[4] = {
-               ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
-               AWE_MAJOR_VERSION,
-       };
-       if (memcmp(name, id_head, 4) == 0)
-               return TRUE;
-       return FALSE;
-}
-
-/* check if the given name matches to the existing list */
-static int is_identical_name(unsigned char *name, sf_list *p) 
-{
-       char *id = p->name;
-       if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
-               return TRUE;
-       return FALSE;
-}
-
-/* check if the given voice info exists */
-static int info_duplicated(sf_list *sf, awe_voice_list *rec)
-{
-       /* search for all sharing lists */
-       for (; sf; sf = sf->shared) {
-               awe_voice_list *p;
-               for (p = sf->infos; p; p = p->next) {
-                       if (p->type == V_ST_NORMAL &&
-                           p->bank == rec->bank &&
-                           p->instr == rec->instr &&
-                           p->v.low == rec->v.low &&
-                           p->v.high == rec->v.high &&
-                           p->v.sample == rec->v.sample)
-                               return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-#endif /* AWE_ALLOW_SAMPLE_SHARING */
-
-
-/* free sf_list record */
-/* linked-list in this function is not cared */
-static void
-awe_free_sf(sf_list *sf)
-{
-       if (sf->infos) {
-               awe_voice_list *p, *next;
-               for (p = sf->infos; p; p = next) {
-                       next = p->next;
-                       kfree(p);
-               }
-       }
-       if (sf->samples) {
-               awe_sample_list *p, *next;
-               for (p = sf->samples; p; p = next) {
-                       next = p->next;
-                       kfree(p);
-               }
-       }
-       kfree(sf);
-}
-
-
-/* open patch; create sf list and set opened flag */
-static int
-awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       awe_open_parm parm;
-       int shared;
-
-       if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
-               return -EFAULT;
-       shared = FALSE;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
-               /* is the previous font the same font? */
-               if (is_identical_name(parm.name, sftail)) {
-                       /* then append to the previous */
-                       shared = TRUE;
-                       awe_reset(0);
-                       if (parm.type & AWE_PAT_LOCKED)
-                               locked_sf_id = current_sf_id;
-               }
-       }
-#endif /* allow sharing */
-       if (! shared) {
-               if (awe_create_sf(parm.type, parm.name)) {
-                       printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
-                       return -ENOMEM;
-               }
-       }
-       patch_opened = TRUE;
-       return current_sf_id;
-}
-
-/* check if the patch is already opened */
-static sf_list *
-check_patch_opened(int type, char *name)
-{
-       if (! patch_opened) {
-               if (awe_create_sf(type, name)) {
-                       printk(KERN_ERR "AWE32: failed to alloc new list\n");
-                       return NULL;
-               }
-               patch_opened = TRUE;
-               return sftail;
-       }
-       return sftail;
-}
-
-/* close the patch; if no voice is loaded, remove the patch */
-static int
-awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch_opened && sftail) {
-               /* if no voice is loaded, release the current patch */
-               if (sftail->infos == NULL) {
-                       awe_reset(0);
-                       awe_remove_samples(current_sf_id - 1);
-               }
-       }
-       patch_opened = 0;
-       return 0;
-}
-
-
-/* remove the latest patch */
-static int
-awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
-               awe_reset(0);
-               awe_remove_samples(current_sf_id - 1);
-       }
-       return 0;
-}
-
-/* allocate voice info list records */
-static awe_voice_list *
-alloc_new_info(void)
-{
-       awe_voice_list *newlist;
-       
-       newlist = kmalloc(sizeof(*newlist), GFP_KERNEL);
-       if (newlist == NULL) {
-               printk(KERN_ERR "AWE32: can't alloc info table\n");
-               return NULL;
-       }
-       return newlist;
-}
-
-/* allocate sample info list records */
-static awe_sample_list *
-alloc_new_sample(void)
-{
-       awe_sample_list *newlist;
-       
-       newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
-       if (newlist == NULL) {
-               printk(KERN_ERR "AWE32: can't alloc sample table\n");
-               return NULL;
-       }
-       return newlist;
-}
-
-/* load voice map */
-static int
-awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
-{
-       awe_voice_map map;
-       awe_voice_list *rec, *p;
-       sf_list *sf;
-
-       /* get the link info */
-       if (count < sizeof(map)) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-               return -EFAULT;
-       
-       /* check if the identical mapping already exists */
-       p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
-       for (; p; p = p->next_instr) {
-               if (p->type == V_ST_MAPPED &&
-                   p->v.start == map.src_instr &&
-                   p->v.end == map.src_bank &&
-                   p->v.fixkey == map.src_key)
-                       return 0; /* already present! */
-       }
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
-               return -ENOMEM;
-
-       if ((rec = alloc_new_info()) == NULL)
-               return -ENOMEM;
-
-       rec->bank = map.map_bank;
-       rec->instr = map.map_instr;
-       rec->type = V_ST_MAPPED;
-       rec->disabled = FALSE;
-       awe_init_voice_info(&rec->v);
-       if (map.map_key >= 0) {
-               rec->v.low = map.map_key;
-               rec->v.high = map.map_key;
-       }
-       rec->v.start = map.src_instr;
-       rec->v.end = map.src_bank;
-       rec->v.fixkey = map.src_key;
-       add_sf_info(sf, rec);
-       add_info_list(rec);
-
-       return 0;
-}
-
-#if 0
-/* probe preset in the current list -- nothing to be loaded */
-static int
-awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       awe_voice_map map;
-       awe_voice_list *p;
-
-       if (! patch_opened)
-               return -EINVAL;
-
-       /* get the link info */
-       if (count < sizeof(map)) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-               return -EFAULT;
-       
-       /* check if the identical mapping already exists */
-       if (sftail == NULL)
-               return -EINVAL;
-       p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
-       for (; p; p = p->next_instr) {
-               if (p->type == V_ST_NORMAL &&
-                   is_identical_holder(p->holder, sftail) &&
-                   p->v.low <= map.src_key &&
-                   p->v.high >= map.src_key)
-                       return 0; /* already present! */
-       }
-#endif /* allow sharing */
-       return -EINVAL;
-}
-#endif
-
-/* probe sample in the current list -- nothing to be loaded */
-static int
-awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       if (! patch_opened)
-               return -EINVAL;
-
-       /* search the specified sample by optarg */
-       if (search_sample_index(sftail, patch->optarg) != NULL)
-               return 0;
-#endif /* allow sharing */
-       return -EINVAL;
-}
-
-               
-/* remove the present instrument layers */
-static int
-remove_info(sf_list *sf, int bank, int instr)
-{
-       awe_voice_list *prev, *next, *p;
-       int removed = 0;
-
-       prev = NULL;
-       for (p = sf->infos; p; p = next) {
-               next = p->next;
-               if (p->type == V_ST_NORMAL &&
-                   p->bank == bank && p->instr == instr) {
-                       /* remove this layer */
-                       if (prev)
-                               prev->next = next;
-                       else
-                               sf->infos = next;
-                       if (p == sf->last_infos)
-                               sf->last_infos = prev;
-                       sf->num_info--;
-                       removed++;
-                       kfree(p);
-               } else
-                       prev = p;
-       }
-       if (removed)
-               rebuild_preset_list();
-       return removed;
-}
-
-/* load voice information data */
-static int
-awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset;
-       awe_voice_rec_hdr hdr;
-       int i;
-       int total_size;
-       sf_list *sf;
-       awe_voice_list *rec;
-
-       if (count < AWE_VOICE_REC_SIZE) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
-               return -EFAULT;
-       offset += AWE_VOICE_REC_SIZE;
-
-       if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
-               printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
-               return -EINVAL;
-       }
-       total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
-       if (count < total_size) {
-               printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
-                      count, hdr.nvoices);
-               return -EINVAL;
-       }
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-               return -ENOMEM;
-
-       switch (hdr.write_mode) {
-       case AWE_WR_EXCLUSIVE:
-               /* exclusive mode - if the instrument already exists,
-                  return error */
-               for (rec = sf->infos; rec; rec = rec->next) {
-                       if (rec->type == V_ST_NORMAL &&
-                           rec->bank == hdr.bank &&
-                           rec->instr == hdr.instr)
-                               return -EINVAL;
-               }
-               break;
-       case AWE_WR_REPLACE:
-               /* replace mode - remove the instrument if it already exists */
-               remove_info(sf, hdr.bank, hdr.instr);
-               break;
-       }
-
-       /* append new layers */
-       for (i = 0; i < hdr.nvoices; i++) {
-               rec = alloc_new_info();
-               if (rec == NULL)
-                       return -ENOMEM;
-
-               rec->bank = hdr.bank;
-               rec->instr = hdr.instr;
-               rec->type = V_ST_NORMAL;
-               rec->disabled = FALSE;
-
-               /* copy awe_voice_info parameters */
-               if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
-                       kfree(rec);
-                       return -EFAULT;
-               }
-               offset += AWE_VOICE_INFO_SIZE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-               if (sf && sf->shared) {
-                       if (info_duplicated(sf, rec)) {
-                               kfree(rec);
-                               continue;
-                       }
-               }
-#endif /* allow sharing */
-               if (rec->v.mode & AWE_MODE_INIT_PARM)
-                       awe_init_voice_parm(&rec->v.parm);
-               add_sf_info(sf, rec);
-               awe_set_sample(rec);
-               add_info_list(rec);
-       }
-
-       return 0;
-}
-
-
-/* remove instrument layers */
-static int
-awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-       unsigned char bank, instr;
-       sf_list *sf;
-
-       if (! patch_opened || (sf = sftail) == NULL) {
-               printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
-               return -EINVAL;
-       }
-
-       bank = ((unsigned short)patch->optarg >> 8) & 0xff;
-       instr = (unsigned short)patch->optarg & 0xff;
-       if (! remove_info(sf, bank, instr))
-               return -EINVAL;
-       return 0;
-}
-
-
-/* load wave sample data */
-static int
-awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset, size;
-       int rc;
-       awe_sample_info tmprec;
-       awe_sample_list *rec;
-       sf_list *sf;
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-               return -ENOMEM;
-
-       size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
-               return -EFAULT;
-       offset += AWE_SAMPLE_INFO_SIZE;
-       if (size != tmprec.size) {
-               printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
-                      tmprec.size, size);
-               return -EINVAL;
-       }
-
-       if (search_sample_index(sf, tmprec.sample) != NULL) {
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-               /* if shared sample, skip this data */
-               if (sf->type & AWE_PAT_SHARED)
-                       return 0;
-#endif /* allow sharing */
-               DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
-               return -EINVAL;
-       }
-
-       if ((rec = alloc_new_sample()) == NULL)
-               return -ENOMEM;
-
-       memcpy(&rec->v, &tmprec, sizeof(tmprec));
-
-       if (rec->v.size > 0) {
-               if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
-                       kfree(rec);
-                       return rc;
-               }
-               sf->mem_ptr += rc;
-       }
-
-       add_sf_sample(sf, rec);
-       return 0;
-}
-
-
-/* replace wave sample data */
-static int
-awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset;
-       int size;
-       int rc;
-       int channels;
-       awe_sample_info cursmp;
-       int save_mem_ptr;
-       sf_list *sf;
-       awe_sample_list *rec;
-
-       if (! patch_opened || (sf = sftail) == NULL) {
-               printk(KERN_WARNING "AWE32: replace: patch not opened\n");
-               return -EINVAL;
-       }
-
-       size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
-               return -EFAULT;
-       offset += AWE_SAMPLE_INFO_SIZE;
-       if (cursmp.size == 0 || size != cursmp.size) {
-               printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
-                      cursmp.size, size);
-               return -EINVAL;
-       }
-       channels = patch->optarg;
-       if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
-               printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
-               return -EINVAL;
-       }
-
-       for (rec = sf->samples; rec; rec = rec->next) {
-               if (rec->v.sample == cursmp.sample)
-                       break;
-       }
-       if (rec == NULL) {
-               printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
-                      cursmp.sample);
-               return -EINVAL;
-       }
-               
-       if (rec->v.size != cursmp.size) {
-               printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
-                      rec->v.size, cursmp.size);
-               return -EINVAL;
-       }
-
-       save_mem_ptr = awe_free_mem_ptr();
-       sftail->mem_ptr = rec->v.start - awe_mem_start;
-       memcpy(&rec->v, &cursmp, sizeof(cursmp));
-       rec->v.sf_id = current_sf_id;
-       if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
-               return rc;
-       sftail->mem_ptr = save_mem_ptr;
-
-       return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-static const char __user *readbuf_addr;
-static int readbuf_offs;
-static int readbuf_flags;
-
-/* initialize read buffer */
-static int
-readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
-{
-       readbuf_addr = addr;
-       readbuf_offs = offset;
-       readbuf_flags = sp->mode_flags;
-       return 0;
-}
-
-/* read directly from user buffer */
-static unsigned short
-readbuf_word(int pos)
-{
-       unsigned short c;
-       /* read from user buffer */
-       if (readbuf_flags & AWE_SAMPLE_8BITS) {
-               unsigned char cc;
-               get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
-               c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
-       } else {
-               get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
-       }
-       if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
-               c ^= 0x8000; /* unsigned -> signed */
-       return c;
-}
-
-#define readbuf_word_cache     readbuf_word
-#define readbuf_end()          /**/
-
-/*----------------------------------------------------------------*/
-
-#define BLANK_LOOP_START       8
-#define BLANK_LOOP_END         40
-#define BLANK_LOOP_SIZE                48
-
-/* loading onto memory - return the actual written size */
-static int 
-awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
-{
-       int i, truesize, dram_offset;
-       awe_sample_info *sp = &list->v;
-       int rc;
-
-       /* be sure loop points start < end */
-       if (sp->loopstart > sp->loopend) {
-               int tmp = sp->loopstart;
-               sp->loopstart = sp->loopend;
-               sp->loopend = tmp;
-       }
-
-       /* compute true data size to be loaded */
-       truesize = sp->size;
-       if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
-               truesize += sp->loopend - sp->loopstart;
-       if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
-               truesize += BLANK_LOOP_SIZE;
-       if (awe_free_mem_ptr() + truesize >= memsize/2) {
-               DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
-               return -ENOSPC;
-       }
-
-       /* recalculate address offset */
-       sp->end -= sp->start;
-       sp->loopstart -= sp->start;
-       sp->loopend -= sp->start;
-
-       dram_offset = awe_free_mem_ptr() + awe_mem_start;
-       sp->start = dram_offset;
-       sp->end += dram_offset;
-       sp->loopstart += dram_offset;
-       sp->loopend += dram_offset;
-
-       /* set the total size (store onto obsolete checksum value) */
-       if (sp->size == 0)
-               sp->checksum = 0;
-       else
-               sp->checksum = truesize;
-
-       if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
-               return rc;
-
-       if (readbuf_init(addr, offset, sp) < 0)
-               return -ENOSPC;
-
-       for (i = 0; i < sp->size; i++) {
-               unsigned short c;
-               c = readbuf_word(i);
-               awe_write_dram(c);
-               if (i == sp->loopend &&
-                   (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
-                       int looplen = sp->loopend - sp->loopstart;
-                       /* copy reverse loop */
-                       int k;
-                       for (k = 1; k <= looplen; k++) {
-                               c = readbuf_word_cache(i - k);
-                               awe_write_dram(c);
-                       }
-                       if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
-                               sp->end += looplen;
-                       } else {
-                               sp->start += looplen;
-                               sp->end += looplen;
-                       }
-               }
-       }
-       readbuf_end();
-
-       /* if no blank loop is attached in the sample, add it */
-       if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
-               for (i = 0; i < BLANK_LOOP_SIZE; i++)
-                       awe_write_dram(0);
-               if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
-                       sp->loopstart = sp->end + BLANK_LOOP_START;
-                       sp->loopend = sp->end + BLANK_LOOP_END;
-               }
-       }
-
-       awe_close_dram();
-
-       /* initialize FM */
-       awe_init_fm();
-
-       return truesize;
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* calculate GUS envelope time:
- * is this correct?  i have no idea..
- */
-static int
-calc_gus_envelope_time(int rate, int start, int end)
-{
-       int r, p, t;
-       r = (3 - ((rate >> 6) & 3)) * 3;
-       p = rate & 0x3f;
-       t = end - start;
-       if (t < 0) t = -t;
-       if (13 > r)
-               t = t << (13 - r);
-       else
-               t = t >> (r - 13);
-       return (t * 10) / (p * 441);
-}
-
-#define calc_gus_sustain(val)  (0x7f - vol_table[(val)/2])
-#define calc_gus_attenuation(val)      vol_table[(val)/2]
-
-/* load GUS patch */
-static int
-awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
-{
-       struct patch_info patch;
-       awe_voice_info *rec;
-       awe_sample_info *smp;
-       awe_voice_list *vrec;
-       awe_sample_list *smprec;
-       int sizeof_patch;
-       int note, rc;
-       sf_list *sf;
-
-       sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
-       if (size < sizeof_patch) {
-               printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
-               return -EFAULT;
-       size -= sizeof_patch;
-       if (size < patch.len) {
-               printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
-                      size, patch.len);
-               return -EINVAL;
-       }
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
-               return -ENOMEM;
-       if ((smprec = alloc_new_sample()) == NULL)
-               return -ENOMEM;
-       if ((vrec = alloc_new_info()) == NULL) {
-               kfree(smprec);
-               return -ENOMEM;
-       }
-
-       smp = &smprec->v;
-       smp->sample = sf->num_sample;
-       smp->start = 0;
-       smp->end = patch.len;
-       smp->loopstart = patch.loop_start;
-       smp->loopend = patch.loop_end;
-       smp->size = patch.len;
-
-       /* set up mode flags */
-       smp->mode_flags = 0;
-       if (!(patch.mode & WAVE_16_BITS))
-               smp->mode_flags |= AWE_SAMPLE_8BITS;
-       if (patch.mode & WAVE_UNSIGNED)
-               smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
-       smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
-       if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
-               smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
-       if (patch.mode & WAVE_BIDIR_LOOP)
-               smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
-       if (patch.mode & WAVE_LOOP_BACK)
-               smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
-
-       DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
-       if (patch.mode & WAVE_16_BITS) {
-               /* convert to word offsets */
-               smp->size /= 2;
-               smp->end /= 2;
-               smp->loopstart /= 2;
-               smp->loopend /= 2;
-       }
-       smp->checksum_flag = 0;
-       smp->checksum = 0;
-
-       if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) {
-               kfree(vrec);
-               return rc;
-       }
-       sf->mem_ptr += rc;
-       add_sf_sample(sf, smprec);
-
-       /* set up voice info */
-       rec = &vrec->v;
-       awe_init_voice_info(rec);
-       rec->sample = sf->num_info; /* the last sample */
-       rec->rate_offset = calc_rate_offset(patch.base_freq);
-       note = freq_to_note(patch.base_note);
-       rec->root = note / 100;
-       rec->tune = -(note % 100);
-       rec->low = freq_to_note(patch.low_note) / 100;
-       rec->high = freq_to_note(patch.high_note) / 100;
-       DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
-                      rec->rate_offset, note,
-                      rec->low, rec->high,
-             patch.low_note, patch.high_note));
-       /* panning position; -128 - 127 => 0-127 */
-       rec->pan = (patch.panning + 128) / 2;
-
-       /* detuning is ignored */
-       /* 6points volume envelope */
-       if (patch.mode & WAVE_ENVELOPES) {
-               int attack, hold, decay, release;
-               attack = calc_gus_envelope_time
-                       (patch.env_rate[0], 0, patch.env_offset[0]);
-               hold = calc_gus_envelope_time
-                       (patch.env_rate[1], patch.env_offset[0],
-                        patch.env_offset[1]);
-               decay = calc_gus_envelope_time
-                       (patch.env_rate[2], patch.env_offset[1],
-                        patch.env_offset[2]);
-               release = calc_gus_envelope_time
-                       (patch.env_rate[3], patch.env_offset[1],
-                        patch.env_offset[4]);
-               release += calc_gus_envelope_time
-                       (patch.env_rate[4], patch.env_offset[3],
-                        patch.env_offset[4]);
-               release += calc_gus_envelope_time
-                       (patch.env_rate[5], patch.env_offset[4],
-                        patch.env_offset[5]);
-               rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
-                       calc_parm_attack(attack);
-               rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
-                       calc_parm_decay(decay);
-               rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
-               DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
-               rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
-       }
-
-       /* tremolo effect */
-       if (patch.mode & WAVE_TREMOLO) {
-               int rate = (patch.tremolo_rate * 1000 / 38) / 42;
-               rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
-               DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
-                              patch.tremolo_rate, patch.tremolo_depth,
-                              rec->parm.tremfrq));
-       }
-       /* vibrato effect */
-       if (patch.mode & WAVE_VIBRATO) {
-               int rate = (patch.vibrato_rate * 1000 / 38) / 42;
-               rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
-               DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
-                              patch.tremolo_rate, patch.tremolo_depth,
-                              rec->parm.tremfrq));
-       }
-       
-       /* scale_freq, scale_factor, volume, and fractions not implemented */
-
-       /* append to the tail of the list */
-       vrec->bank = ctrls[AWE_MD_GUS_BANK];
-       vrec->instr = patch.instr_no;
-       vrec->disabled = FALSE;
-       vrec->type = V_ST_NORMAL;
-
-       add_sf_info(sf, vrec);
-       add_info_list(vrec);
-
-       /* set the voice index */
-       awe_set_sample(vrec);
-
-       return 0;
-}
-
-#endif  /* AWE_HAS_GUS_COMPATIBILITY */
-
-/*
- * sample and voice list handlers
- */
-
-/* append this to the current sf list */
-static void add_sf_info(sf_list *sf, awe_voice_list *rec)
-{
-       if (sf == NULL)
-               return;
-       rec->holder = sf;
-       rec->v.sf_id = sf->sf_id;
-       if (sf->last_infos)
-               sf->last_infos->next = rec;
-       else
-               sf->infos = rec;
-       sf->last_infos = rec;
-       rec->next = NULL;
-       sf->num_info++;
-}
-
-/* prepend this sample to sf list */
-static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
-{
-       if (sf == NULL)
-               return;
-       rec->holder = sf;
-       rec->v.sf_id = sf->sf_id;
-       if (sf->last_samples)
-               sf->last_samples->next = rec;
-       else
-               sf->samples = rec;
-       sf->last_samples = rec;
-       rec->next = NULL;
-       sf->num_sample++;
-}
-
-/* purge the old records which don't belong with the same file id */
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
-{
-       rec->next_instr = next;
-       if (rec->bank == AWE_DRUM_BANK) {
-               /* remove samples with the same note range */
-               awe_voice_list *cur, *prev = rec;
-               int low = rec->v.low;
-               int high = rec->v.high;
-               for (cur = next; cur; cur = cur->next_instr) {
-                       if (cur->v.low == low &&
-                           cur->v.high == high &&
-                           ! is_identical_holder(cur->holder, rec->holder))
-                               prev->next_instr = cur->next_instr;
-                       else
-                               prev = cur;
-               }
-       } else {
-               if (! is_identical_holder(next->holder, rec->holder))
-                       /* remove all samples */
-                       rec->next_instr = NULL;
-       }
-}
-
-/* prepend to top of the preset table */
-static void add_info_list(awe_voice_list *rec)
-{
-       awe_voice_list *prev, *cur;
-       int key;
-
-       if (rec->disabled)
-               return;
-
-       key = awe_search_key(rec->bank, rec->instr, rec->v.low);
-       prev = NULL;
-       for (cur = preset_table[key]; cur; cur = cur->next_bank) {
-               /* search the first record with the same bank number */
-               if (cur->instr == rec->instr && cur->bank == rec->bank) {
-                       /* replace the list with the new record */
-                       rec->next_bank = cur->next_bank;
-                       if (prev)
-                               prev->next_bank = rec;
-                       else
-                               preset_table[key] = rec;
-                       purge_old_list(rec, cur);
-                       return;
-               }
-               prev = cur;
-       }
-
-       /* this is the first bank record.. just add this */
-       rec->next_instr = NULL;
-       rec->next_bank = preset_table[key];
-       preset_table[key] = rec;
-}
-
-/* remove samples later than the specified sf_id */
-static void
-awe_remove_samples(int sf_id)
-{
-       sf_list *p, *prev;
-
-       if (sf_id <= 0) {
-               awe_reset_samples();
-               return;
-       }
-       /* already removed? */
-       if (current_sf_id <= sf_id)
-               return;
-
-       for (p = sftail; p; p = prev) {
-               if (p->sf_id <= sf_id)
-                       break;
-               prev = p->prev;
-               awe_free_sf(p);
-       }
-       sftail = p;
-       if (sftail) {
-               sf_id = sftail->sf_id;
-               sftail->next = NULL;
-       } else {
-               sf_id = 0;
-               sfhead = NULL;
-       }
-       current_sf_id = sf_id;
-       if (locked_sf_id > sf_id)
-               locked_sf_id = sf_id;
-
-       rebuild_preset_list();
-}
-
-/* rebuild preset search list */
-static void rebuild_preset_list(void)
-{
-       sf_list *p;
-       awe_voice_list *rec;
-
-       memset(preset_table, 0, sizeof(preset_table));
-
-       for (p = sfhead; p; p = p->next) {
-               for (rec = p->infos; rec; rec = rec->next)
-                       add_info_list(rec);
-       }
-}
-
-/* compare the given sf_id pair */
-static int is_identical_holder(sf_list *sf1, sf_list *sf2)
-{
-       if (sf1 == NULL || sf2 == NULL)
-               return FALSE;
-       if (sf1 == sf2)
-               return TRUE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       {
-               /* compare with the sharing id */
-               sf_list *p;
-               int counter = 0;
-               if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
-                       sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
-               }
-               for (p = sf1->shared; p; p = p->shared) {
-                       if (counter++ > current_sf_id)
-                               break; /* strange sharing loop.. quit */
-                       if (p == sf2)
-                               return TRUE;
-               }
-       }
-#endif /* allow sharing */
-       return FALSE;
-}
-
-/* search the sample index matching with the given sample id */
-static awe_sample_list *
-search_sample_index(sf_list *sf, int sample)
-{
-       awe_sample_list *p;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       int counter = 0;
-       while (sf) {
-               for (p = sf->samples; p; p = p->next) {
-                       if (p->v.sample == sample)
-                               return p;
-               }
-               sf = sf->shared;
-               if (counter++ > current_sf_id)
-                       break; /* strange sharing loop.. quit */
-       }
-#else
-       if (sf) {
-               for (p = sf->samples; p; p = p->next) {
-                       if (p->v.sample == sample)
-                               return p;
-               }
-       }
-#endif
-       return NULL;
-}
-
-/* search the specified sample */
-/* non-zero = found */
-static short
-awe_set_sample(awe_voice_list *rec)
-{
-       awe_sample_list *smp;
-       awe_voice_info *vp = &rec->v;
-
-       vp->index = 0;
-       if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
-               return 0;
-
-       /* set the actual sample offsets */
-       vp->start += smp->v.start;
-       vp->end += smp->v.end;
-       vp->loopstart += smp->v.loopstart;
-       vp->loopend += smp->v.loopend;
-       /* copy mode flags */
-       vp->mode = smp->v.mode_flags;
-       /* set flag */
-       vp->index = 1;
-
-       return 1;
-}
-
-
-/*
- * voice allocation
- */
-
-/* look for all voices associated with the specified note & velocity */
-static int
-awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
-                       awe_voice_info **vlist)
-{
-       int nvoices;
-
-       nvoices = 0;
-       for (; rec; rec = rec->next_instr) {
-               if (note >= rec->v.low &&
-                   note <= rec->v.high &&
-                   velocity >= rec->v.vellow &&
-                   velocity <= rec->v.velhigh) {
-                       if (rec->type == V_ST_MAPPED) {
-                               /* mapper */
-                               vlist[0] = &rec->v;
-                               return -1;
-                       }
-                       vlist[nvoices++] = &rec->v;
-                       if (nvoices >= AWE_MAX_VOICES)
-                               break;
-               }
-       }
-       return nvoices; 
-}
-
-/* store the voice list from the specified note and velocity.
-   if the preset is mapped, seek for the destination preset, and rewrite
-   the note number if necessary.
-   */
-static int
-really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
-{
-       int nvoices;
-       awe_voice_list *vrec;
-       int level = 0;
-
-       for (;;) {
-               vrec = awe_search_instr(bank, instr, *note);
-               nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               if (nvoices == 0) {
-                       if (bank == AWE_DRUM_BANK)
-                               /* search default drumset */
-                               vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
-                       else
-                               /* search default preset */
-                               vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
-                       nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               }
-               if (nvoices == 0) {
-                       if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
-                               /* search default drumset */
-                               vrec = awe_search_instr(bank, 0, *note);
-                       else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
-                               /* search default preset */
-                               vrec = awe_search_instr(0, instr, *note);
-                       nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               }
-               if (nvoices < 0) { /* mapping */
-                       int key = vlist[0]->fixkey;
-                       instr = vlist[0]->start;
-                       bank = vlist[0]->end;
-                       if (level++ > 5) {
-                               printk(KERN_ERR "AWE32: too deep mapping level\n");
-                               return 0;
-                       }
-                       if (key >= 0)
-                               *note = key;
-               } else
-                       break;
-       }
-
-       return nvoices;
-}
-
-/* allocate voices corresponding note and velocity; supports multiple insts. */
-static void
-awe_alloc_multi_voices(int ch, int note, int velocity, int key)
-{
-       int i, v, nvoices, bank;
-       awe_voice_info *vlist[AWE_MAX_VOICES];
-
-       if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
-               bank = AWE_DRUM_BANK; /* always search drumset */
-       else
-               bank = channels[ch].bank;
-
-       /* check the possible voices; note may be changeable if mapped */
-       nvoices = really_alloc_voices(bank, channels[ch].instr,
-                                     &note, velocity, vlist);
-
-       /* set the voices */
-       current_alloc_time++;
-       for (i = 0; i < nvoices; i++) {
-               v = awe_clear_voice();
-               voices[v].key = key;
-               voices[v].ch = ch;
-               voices[v].note = note;
-               voices[v].velocity = velocity;
-               voices[v].time = current_alloc_time;
-               voices[v].cinfo = &channels[ch];
-               voices[v].sample = vlist[i];
-               voices[v].state = AWE_ST_MARK;
-               voices[v].layer = nvoices - i - 1;  /* in reverse order */
-       }
-
-       /* clear the mark in allocated voices */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].state == AWE_ST_MARK)
-                       voices[i].state = AWE_ST_OFF;
-                       
-       }
-}
-
-
-/* search an empty voice.
-   if no empty voice is found, at least terminate a voice
-   */
-static int
-awe_clear_voice(void)
-{
-       enum {
-               OFF=0, RELEASED, SUSTAINED, PLAYING, END
-       };
-       struct voice_candidate_t {
-               int best;
-               int time;
-               int vtarget;
-       } candidate[END];
-       int i, type, vtarget;
-
-       vtarget = 0xffff;
-       for (type = OFF; type < END; type++) {
-               candidate[type].best = -1;
-               candidate[type].time = current_alloc_time + 1;
-               candidate[type].vtarget = vtarget;
-       }
-
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].state & AWE_ST_OFF)
-                       type = OFF;
-               else if (voices[i].state & AWE_ST_RELEASED)
-                       type = RELEASED;
-               else if (voices[i].state & AWE_ST_SUSTAINED)
-                       type = SUSTAINED;
-               else if (voices[i].state & ~AWE_ST_MARK)
-                       type = PLAYING;
-               else
-                       continue;
-#ifdef AWE_CHECK_VTARGET
-               /* get current volume */
-               vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
-#endif
-               if (candidate[type].best < 0 ||
-                   vtarget < candidate[type].vtarget ||
-                   (vtarget == candidate[type].vtarget &&
-                    voices[i].time < candidate[type].time)) {
-                       candidate[type].best = i;
-                       candidate[type].time = voices[i].time;
-                       candidate[type].vtarget = vtarget;
-               }
-       }
-
-       for (type = OFF; type < END; type++) {
-               if ((i = candidate[type].best) >= 0) {
-                       if (voices[i].state != AWE_ST_OFF)
-                               awe_terminate(i);
-                       awe_voice_init(i, TRUE);
-                       return i;
-               }
-       }
-       return 0;
-}
-
-
-/* search sample for the specified note & velocity and set it on the voice;
- * note that voice is the voice index (not channel index)
- */
-static void
-awe_alloc_one_voice(int voice, int note, int velocity)
-{
-       int ch, nvoices, bank;
-       awe_voice_info *vlist[AWE_MAX_VOICES];
-
-       ch = voices[voice].ch;
-       if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
-               bank = AWE_DRUM_BANK; /* always search drumset */
-       else
-               bank = voices[voice].cinfo->bank;
-
-       nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
-                                     &note, velocity, vlist);
-       if (nvoices > 0) {
-               voices[voice].time = ++current_alloc_time;
-               voices[voice].sample = vlist[0]; /* use the first one */
-               voices[voice].layer = 0;
-               voices[voice].note = note;
-               voices[voice].velocity = velocity;
-       }
-}
-
-
-/*
- * sequencer2 functions
- */
-
-/* search an empty voice; used by sequencer2 */
-static int
-awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-       playing_mode = AWE_PLAY_MULTI2;
-       awe_info.nr_voices = AWE_MAX_CHANNELS;
-       return awe_clear_voice();
-}
-
-
-/* set up voice; used by sequencer2 */
-static void
-awe_setup_voice(int dev, int voice, int chn)
-{
-       struct channel_info *info;
-       if (synth_devs[dev] == NULL ||
-           (info = &synth_devs[dev]->chn_info[chn]) == NULL)
-               return;
-
-       if (voice < 0 || voice >= awe_max_voices)
-               return;
-
-       DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
-       channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
-       channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
-       channels[chn].panning =
-               info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
-       channels[chn].bender = info->bender_value; /* zero center */
-       channels[chn].bank = info->controllers[CTL_BANK_SELECT];
-       channels[chn].sustained = info->controllers[CTL_SUSTAIN];
-       if (info->controllers[CTL_EXT_EFF_DEPTH]) {
-               FX_SET(&channels[chn].fx, AWE_FX_REVERB,
-                      info->controllers[CTL_EXT_EFF_DEPTH] * 2);
-       }
-       if (info->controllers[CTL_CHORUS_DEPTH]) {
-               FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
-                      info->controllers[CTL_CHORUS_DEPTH] * 2);
-       }
-       awe_set_instr(dev, chn, info->pgm_num);
-}
-
-
-#ifdef CONFIG_AWE32_MIXER
-/*
- * AWE32 mixer device control
- */
-
-static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
-
-static int my_mixerdev = -1;
-
-static struct mixer_operations awe_mixer_operations = {
-       .owner  = THIS_MODULE,
-       .id     = "AWE",
-       .name   = "AWE32 Equalizer",
-       .ioctl  = awe_mixer_ioctl,
-};
-
-static void __init attach_mixer(void)
-{
-       if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
-               mixer_devs[my_mixerdev] = &awe_mixer_operations;
-       }
-}
-
-static void unload_mixer(void)
-{
-       if (my_mixerdev >= 0)
-               sound_unload_mixerdev(my_mixerdev);
-}
-
-static int
-awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
-       int i, level, value;
-
-       if (((cmd >> 8) & 0xff) != 'M')
-               return -EINVAL;
-
-       if (get_user(level, (int __user *)arg))
-               return -EFAULT;
-       level = ((level & 0xff) + (level >> 8)) / 2;
-       DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
-
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-               switch (cmd & 0xff) {
-               case SOUND_MIXER_BASS:
-                       value = level * 12 / 100;
-                       if (value >= 12)
-                               value = 11;
-                       ctrls[AWE_MD_BASS_LEVEL] = value;
-                       awe_update_equalizer();
-                       break;
-               case SOUND_MIXER_TREBLE:
-                       value = level * 12 / 100;
-                       if (value >= 12)
-                               value = 11;
-                       ctrls[AWE_MD_TREBLE_LEVEL] = value;
-                       awe_update_equalizer();
-                       break;
-               case SOUND_MIXER_VOLUME:
-                       level = level * 127 / 100;
-                       if (level >= 128) level = 127;
-                       atten_relative = FALSE;
-                       atten_offset = vol_table[level];
-                       awe_update_volume();
-                       break;
-               }
-       }
-       switch (cmd & 0xff) {
-       case SOUND_MIXER_BASS:
-               level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_TREBLE:
-               level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_VOLUME:
-               value = atten_offset;
-               if (atten_relative)
-                       value += ctrls[AWE_MD_ZERO_ATTEN];
-               for (i = 127; i > 0; i--) {
-                       if (value <= vol_table[i])
-                               break;
-               }
-               level = i * 100 / 127;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_DEVMASK:
-               level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
-               break;
-       default:
-               level = 0;
-               break;
-       }
-       if (put_user(level, (int __user *)arg))
-               return -EFAULT;
-       return level;
-}
-#endif /* CONFIG_AWE32_MIXER */
-
-
-/*
- * initialization of Emu8000
- */
-
-/* intiailize audio channels */
-static void
-awe_init_audio(void)
-{
-       int ch;
-
-       /* turn off envelope engines */
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke(AWE_DCYSUSV(ch), 0x80);
-       }
-  
-       /* reset all other parameters to zero */
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke(AWE_ENVVOL(ch), 0);
-               awe_poke(AWE_ENVVAL(ch), 0);
-               awe_poke(AWE_DCYSUS(ch), 0);
-               awe_poke(AWE_ATKHLDV(ch), 0);
-               awe_poke(AWE_LFO1VAL(ch), 0);
-               awe_poke(AWE_ATKHLD(ch), 0);
-               awe_poke(AWE_LFO2VAL(ch), 0);
-               awe_poke(AWE_IP(ch), 0);
-               awe_poke(AWE_IFATN(ch), 0);
-               awe_poke(AWE_PEFE(ch), 0);
-               awe_poke(AWE_FMMOD(ch), 0);
-               awe_poke(AWE_TREMFRQ(ch), 0);
-               awe_poke(AWE_FM2FRQ2(ch), 0);
-               awe_poke_dw(AWE_PTRX(ch), 0);
-               awe_poke_dw(AWE_VTFT(ch), 0);
-               awe_poke_dw(AWE_PSST(ch), 0);
-               awe_poke_dw(AWE_CSL(ch), 0);
-               awe_poke_dw(AWE_CCCA(ch), 0);
-       }
-
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke_dw(AWE_CPF(ch), 0);
-               awe_poke_dw(AWE_CVCF(ch), 0);
-       }
-}
-
-
-/* initialize DMA address */
-static void
-awe_init_dma(void)
-{
-       awe_poke_dw(AWE_SMALR, 0);
-       awe_poke_dw(AWE_SMARR, 0);
-       awe_poke_dw(AWE_SMALW, 0);
-       awe_poke_dw(AWE_SMARW, 0);
-}
-
-
-/* initialization arrays; from ADIP */
-
-static unsigned short init1[128] = {
-       0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
-       0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
-       0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
-       0x33ff, 0x0c30,  0x37ff, 0x0d30, 0x3bff, 0x0e30,  0x3fff, 0x0f30,
-
-       0x43ff, 0x0030,  0x47ff, 0x0130, 0x4bff, 0x0230,  0x4fff, 0x0330,
-       0x53ff, 0x0430,  0x57ff, 0x0530, 0x5bff, 0x0630,  0x5fff, 0x0730,
-       0x63ff, 0x0830,  0x67ff, 0x0930, 0x6bff, 0x0a30,  0x6fff, 0x0b30,
-       0x73ff, 0x0c30,  0x77ff, 0x0d30, 0x7bff, 0x0e30,  0x7fff, 0x0f30,
-
-       0x83ff, 0x0030,  0x87ff, 0x0130, 0x8bff, 0x0230,  0x8fff, 0x0330,
-       0x93ff, 0x0430,  0x97ff, 0x0530, 0x9bff, 0x0630,  0x9fff, 0x0730,
-       0xa3ff, 0x0830,  0xa7ff, 0x0930, 0xabff, 0x0a30,  0xafff, 0x0b30,
-       0xb3ff, 0x0c30,  0xb7ff, 0x0d30, 0xbbff, 0x0e30,  0xbfff, 0x0f30,
-
-       0xc3ff, 0x0030,  0xc7ff, 0x0130, 0xcbff, 0x0230,  0xcfff, 0x0330,
-       0xd3ff, 0x0430,  0xd7ff, 0x0530, 0xdbff, 0x0630,  0xdfff, 0x0730,
-       0xe3ff, 0x0830,  0xe7ff, 0x0930, 0xebff, 0x0a30,  0xefff, 0x0b30,
-       0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
-};
-
-static unsigned short init2[128] = {
-       0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
-       0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
-       0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
-       0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
-
-       0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
-       0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
-       0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
-       0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
-
-       0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
-       0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
-       0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
-       0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
-
-       0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
-       0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
-       0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
-       0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
-};
-
-static unsigned short init3[128] = {
-       0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-       0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
-       0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
-       0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
-
-       0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
-       0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
-       0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
-       0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
-
-       0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
-       0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
-       0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
-       0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
-
-       0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
-       0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
-       0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
-       0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-static unsigned short init4[128] = {
-       0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-       0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
-       0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
-       0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
-
-       0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
-       0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
-       0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
-       0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
-
-       0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
-       0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
-       0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
-       0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
-
-       0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
-       0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
-       0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
-       0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-
-/* send initialization arrays to start up */
-static void
-awe_init_array(void)
-{
-       awe_send_array(init1);
-       awe_wait(1024);
-       awe_send_array(init2);
-       awe_send_array(init3);
-       awe_poke_dw(AWE_HWCF4, 0);
-       awe_poke_dw(AWE_HWCF5, 0x83);
-       awe_poke_dw(AWE_HWCF6, 0x8000);
-       awe_send_array(init4);
-}
-
-/* send an initialization array */
-static void
-awe_send_array(unsigned short *data)
-{
-       int i;
-       unsigned short *p;
-
-       p = data;
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT1(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT2(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT3(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT4(i), *p);
-}
-
-
-/*
- * set up awe32 channels to some known state.
- */
-
-/* set the envelope & LFO parameters to the default values; see ADIP */
-static void
-awe_tweak_voice(int i)
-{
-       /* set all mod/vol envelope shape to minimum */
-       awe_poke(AWE_ENVVOL(i), 0x8000);
-       awe_poke(AWE_ENVVAL(i), 0x8000);
-       awe_poke(AWE_DCYSUS(i), 0x7F7F);
-       awe_poke(AWE_ATKHLDV(i), 0x7F7F);
-       awe_poke(AWE_ATKHLD(i), 0x7F7F);
-       awe_poke(AWE_PEFE(i), 0);  /* mod envelope height to zero */
-       awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
-       awe_poke(AWE_LFO2VAL(i), 0x8000);
-       awe_poke(AWE_IP(i), 0xE000);    /* no pitch shift */
-       awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
-       awe_poke(AWE_FMMOD(i), 0);
-       awe_poke(AWE_TREMFRQ(i), 0);
-       awe_poke(AWE_FM2FRQ2(i), 0);
-}
-
-static void
-awe_tweak(void)
-{
-       int i;
-       /* reset all channels */
-       for (i = 0; i < awe_max_voices; i++)
-               awe_tweak_voice(i);
-}
-
-
-/*
- *  initializes the FM section of AWE32;
- *   see Vince Vu's unofficial AWE32 programming guide
- */
-
-static void
-awe_init_fm(void)
-{
-#ifndef AWE_ALWAYS_INIT_FM
-       /* if no extended memory is on board.. */
-       if (memsize <= 0)
-               return;
-#endif
-       DEBUG(3,printk("AWE32: initializing FM\n"));
-
-       /* Initialize the last two channels for DRAM refresh and producing
-          the reverb and chorus effects for Yamaha OPL-3 synthesizer */
-
-       /* 31: FM left channel, 0xffffe0-0xffffe8 */
-       awe_poke(AWE_DCYSUSV(30), 0x80);
-       awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
-       awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
-                   (DEF_FM_CHORUS_DEPTH << 24));
-       awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
-       awe_poke_dw(AWE_CPF(30), 0);
-       awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
-
-       /* 32: FM right channel, 0xfffff0-0xfffff8 */
-       awe_poke(AWE_DCYSUSV(31), 0x80);
-       awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
-       awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
-                   (DEF_FM_CHORUS_DEPTH << 24));
-       awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
-       awe_poke_dw(AWE_CPF(31), 0x8000);
-       awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
-
-       /* skew volume & cutoff */
-       awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
-       awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
-
-       voices[30].state = AWE_ST_FM;
-       voices[31].state = AWE_ST_FM;
-
-       /* change maximum channels to 30 */
-       awe_max_voices = AWE_NORMAL_VOICES;
-       if (playing_mode == AWE_PLAY_DIRECT)
-               awe_info.nr_voices = awe_max_voices;
-       else
-               awe_info.nr_voices = AWE_MAX_CHANNELS;
-       voice_alloc->max_voice = awe_max_voices;
-}
-
-/*
- *  AWE32 DRAM access routines
- */
-
-/* open DRAM write accessing mode */
-static int
-awe_open_dram_for_write(int offset, int channels)
-{
-       int vidx[AWE_NORMAL_VOICES];
-       int i;
-
-       if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
-               channels = AWE_NORMAL_VOICES;
-               for (i = 0; i < AWE_NORMAL_VOICES; i++)
-                       vidx[i] = i;
-       } else {
-               for (i = 0; i < channels; i++) {
-                       vidx[i] = awe_clear_voice();
-                       voices[vidx[i]].state = AWE_ST_MARK;
-               }
-       }
-
-       /* use all channels for DMA transfer */
-       for (i = 0; i < channels; i++) {
-               if (vidx[i] < 0) continue;
-               awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
-               awe_poke_dw(AWE_VTFT(vidx[i]), 0);
-               awe_poke_dw(AWE_CVCF(vidx[i]), 0);
-               awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
-               awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
-               awe_poke_dw(AWE_PSST(vidx[i]), 0);
-               awe_poke_dw(AWE_CSL(vidx[i]), 0);
-               awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
-               voices[vidx[i]].state = AWE_ST_DRAM;
-       }
-       /* point channels 31 & 32 to ROM samples for DRAM refresh */
-       awe_poke_dw(AWE_VTFT(30), 0);
-       awe_poke_dw(AWE_PSST(30), 0x1d8);
-       awe_poke_dw(AWE_CSL(30), 0x1e0);
-       awe_poke_dw(AWE_CCCA(30), 0x1d8);
-       awe_poke_dw(AWE_VTFT(31), 0);
-       awe_poke_dw(AWE_PSST(31), 0x1d8);
-       awe_poke_dw(AWE_CSL(31), 0x1e0);
-       awe_poke_dw(AWE_CCCA(31), 0x1d8);
-       voices[30].state = AWE_ST_FM;
-       voices[31].state = AWE_ST_FM;
-
-       /* if full bit is on, not ready to write on */
-       if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
-               for (i = 0; i < channels; i++) {
-                       awe_poke_dw(AWE_CCCA(vidx[i]), 0);
-                       voices[vidx[i]].state = AWE_ST_OFF;
-               }
-               printk("awe: not ready to write..\n");
-               return -EPERM;
-       }
-
-       /* set address to write */
-       awe_poke_dw(AWE_SMALW, offset);
-
-       return 0;
-}
-
-/* open DRAM for RAM size detection */
-static void
-awe_open_dram_for_check(void)
-{
-       int i;
-       for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-               awe_poke(AWE_DCYSUSV(i), 0x80);
-               awe_poke_dw(AWE_VTFT(i), 0);
-               awe_poke_dw(AWE_CVCF(i), 0);
-               awe_poke_dw(AWE_PTRX(i), 0x40000000);
-               awe_poke_dw(AWE_CPF(i), 0x40000000);
-               awe_poke_dw(AWE_PSST(i), 0);
-               awe_poke_dw(AWE_CSL(i), 0);
-               if (i & 1) /* DMA write */
-                       awe_poke_dw(AWE_CCCA(i), 0x06000000);
-               else       /* DMA read */
-                       awe_poke_dw(AWE_CCCA(i), 0x04000000);
-               voices[i].state = AWE_ST_DRAM;
-       }
-}
-
-
-/* close dram access */
-static void
-awe_close_dram(void)
-{
-       int i;
-       /* wait until FULL bit in SMAxW register be false */
-       for (i = 0; i < 10000; i++) {
-               if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
-                       break;
-               awe_wait(10);
-       }
-
-       for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-               if (voices[i].state == AWE_ST_DRAM) {
-                       awe_poke_dw(AWE_CCCA(i), 0);
-                       awe_poke(AWE_DCYSUSV(i), 0x807F);
-                       voices[i].state = AWE_ST_OFF;
-               }
-       }
-}
-
-
-/*
- * check dram size on AWE board
- */
-
-/* any three numbers you like */
-#define UNIQUE_ID1     0x1234
-#define UNIQUE_ID2     0x4321
-#define UNIQUE_ID3     0xABCD
-
-static void __init
-awe_check_dram(void)
-{
-       if (awe_present) /* already initialized */
-               return;
-
-       if (memsize >= 0) { /* given by config file or module option */
-               memsize *= 1024; /* convert to Kbytes */
-               return;
-       }
-
-       awe_open_dram_for_check();
-
-       memsize = 0;
-
-       /* set up unique two id numbers */
-       awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
-       awe_poke(AWE_SMLD, UNIQUE_ID1);
-       awe_poke(AWE_SMLD, UNIQUE_ID2);
-
-       while (memsize < AWE_MAX_DRAM_SIZE) {
-               awe_wait(5);
-               /* read a data on the DRAM start address */
-               awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
-               awe_peek(AWE_SMLD); /* discard stale data  */
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
-                       break;
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
-                       break;
-               memsize += 512;  /* increment 512kbytes */
-               /* Write a unique data on the test address;
-                * if the address is out of range, the data is written on
-                * 0x200000(=AWE_DRAM_OFFSET).  Then the two id words are
-                * broken by this data.
-                */
-               awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
-               awe_poke(AWE_SMLD, UNIQUE_ID3);
-               awe_wait(5);
-               /* read a data on the just written DRAM address */
-               awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
-               awe_peek(AWE_SMLD); /* discard stale data  */
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
-                       break;
-       }
-       awe_close_dram();
-
-       DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
-
-       /* convert to Kbytes */
-       memsize *= 1024;
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * chorus and reverb controls; from VV's guide
- */
-
-/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
-static char chorus_defined[AWE_CHORUS_NUMBERS];
-static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
-       {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
-       {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
-       {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
-       {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
-       {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
-       {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
-       {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
-       {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
-};
-
-static int
-awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
-               printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
-               return -EINVAL;
-       }
-       if (count < sizeof(awe_chorus_fx_rec)) {
-               printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-                          sizeof(awe_chorus_fx_rec)))
-               return -EFAULT;
-       chorus_defined[patch->optarg] = TRUE;
-       return 0;
-}
-
-static void
-awe_set_chorus_mode(int effect)
-{
-       if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
-           (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
-               return;
-       awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
-       awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
-       awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
-       awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
-       awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
-       awe_poke_dw(AWE_HWCF6, 0x8000);
-       awe_poke_dw(AWE_HWCF7, 0x0000);
-}
-
-static void
-awe_update_chorus_mode(void)
-{
-       awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
-}
-
-/*----------------------------------------------------------------*/
-
-/* reverb mode settings; write the following 28 data of 16 bit length
- *   on the corresponding ports in the reverb_cmds array
- */
-static char reverb_defined[AWE_CHORUS_NUMBERS];
-static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
-{{  /* room 1 */
-       0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
-       0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
-       0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 2 */
-       0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 3 */
-       0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
-       0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
-       0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
-}},
-{{  /* hall 1 */
-       0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
-       0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
-}},
-{{  /* hall 2 */
-       0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
-       0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
-       0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* plate */
-       0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
-       0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* delay */
-       0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
-       0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-       0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-       0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-{{  /* panning delay */
-       0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
-       0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-       0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-       0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-};
-
-static struct ReverbCmdPair {
-       unsigned short cmd, port;
-} reverb_cmds[28] = {
-  {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
-  {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
-  {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
-  {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
-  {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
-  {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
-  {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
-};
-
-static int
-awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
-               printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
-               return -EINVAL;
-       }
-       if (count < sizeof(awe_reverb_fx_rec)) {
-               printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-                          sizeof(awe_reverb_fx_rec)))
-               return -EFAULT;
-       reverb_defined[patch->optarg] = TRUE;
-       return 0;
-}
-
-static void
-awe_set_reverb_mode(int effect)
-{
-       int i;
-       if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
-           (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
-               return;
-       for (i = 0; i < 28; i++)
-               awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
-                        reverb_parm[effect].parms[i]);
-}
-
-static void
-awe_update_reverb_mode(void)
-{
-       awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
-}
-
-/*
- * treble/bass equalizer control
- */
-
-static unsigned short bass_parm[12][3] = {
-       {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
-       {0xD25B, 0xD35B, 0x0000}, /*  -8 */
-       {0xD24C, 0xD34C, 0x0000}, /*  -6 */
-       {0xD23D, 0xD33D, 0x0000}, /*  -4 */
-       {0xD21F, 0xD31F, 0x0000}, /*  -2 */
-       {0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
-       {0xC219, 0xC319, 0x0001}, /*  +2 */
-       {0xC22A, 0xC32A, 0x0001}, /*  +4 */
-       {0xC24C, 0xC34C, 0x0001}, /*  +6 */
-       {0xC26E, 0xC36E, 0x0001}, /*  +8 */
-       {0xC248, 0xC348, 0x0002}, /* +10 */
-       {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
-};
-
-static unsigned short treble_parm[12][9] = {
-       {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
-       {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
-       {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
-       {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
-};
-
-
-/*
- * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
- */
-static void
-awe_equalizer(int bass, int treble)
-{
-       unsigned short w;
-
-       if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
-               return;
-       awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
-       awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
-       awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
-       awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
-       awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
-       awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
-       awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
-       awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
-       awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
-       awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
-       w = bass_parm[bass][2] + treble_parm[treble][8];
-       awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
-       awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
-}
-
-static void awe_update_equalizer(void)
-{
-       awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef CONFIG_AWE32_MIDIEMU
-
-/*
- * Emu8000 MIDI Emulation
- */
-
-/*
- * midi queue record
- */
-
-/* queue type */
-enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
-
-#define MAX_MIDIBUF    64
-
-/* midi status */
-typedef struct MidiStatus {
-       int queue;      /* queue type */
-       int qlen;       /* queue length */
-       int read;       /* chars read */
-       int status;     /* current status */
-       int chan;       /* current channel */
-       unsigned char buf[MAX_MIDIBUF];
-} MidiStatus;
-
-/* MIDI mode type */
-enum { MODE_GM, MODE_GS, MODE_XG, };
-
-/* NRPN / CC -> Emu8000 parameter converter */
-typedef struct {
-       int control;
-       int awe_effect;
-       unsigned short (*convert)(int val);
-} ConvTable;
-
-
-/*
- * prototypes
- */
-
-static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
-static void awe_midi_close(int dev);
-static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
-static int awe_midi_outputc(int dev, unsigned char midi_byte);
-
-static void init_midi_status(MidiStatus *st);
-static void clear_rpn(void);
-static void get_midi_char(MidiStatus *st, int c);
-/*static void queue_varlen(MidiStatus *st, int c);*/
-static void special_event(MidiStatus *st, int c);
-static void queue_read(MidiStatus *st, int c);
-static void midi_note_on(MidiStatus *st);
-static void midi_note_off(MidiStatus *st);
-static void midi_key_pressure(MidiStatus *st);
-static void midi_channel_pressure(MidiStatus *st);
-static void midi_pitch_wheel(MidiStatus *st);
-static void midi_program_change(MidiStatus *st);
-static void midi_control_change(MidiStatus *st);
-static void midi_select_bank(MidiStatus *st, int val);
-static void midi_nrpn_event(MidiStatus *st);
-static void midi_rpn_event(MidiStatus *st);
-static void midi_detune(int chan, int coarse, int fine);
-static void midi_system_exclusive(MidiStatus *st);
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int xg_control_change(MidiStatus *st, int cmd, int val);
-
-#define numberof(ary)  (sizeof(ary)/sizeof(ary[0]))
-
-
-/*
- * OSS Midi device record
- */
-
-static struct midi_operations awe_midi_operations =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"AWE Midi Emu", 0, 0, SNDCARD_SB},
-       .in_info        = {0},
-       .open           = awe_midi_open, /*open*/
-       .close          = awe_midi_close, /*close*/
-       .ioctl          = awe_midi_ioctl, /*ioctl*/
-       .outputc        = awe_midi_outputc, /*outputc*/
-};
-
-static int my_mididev = -1;
-
-static void __init attach_midiemu(void)
-{
-       if ((my_mididev = sound_alloc_mididev()) < 0)
-               printk ("Sound: Too many midi devices detected\n");
-       else
-               midi_devs[my_mididev] = &awe_midi_operations;
-}
-
-static void unload_midiemu(void)
-{
-       if (my_mididev >= 0)
-               sound_unload_mididev(my_mididev);
-}
-
-
-/*
- * open/close midi device
- */
-
-static int midi_opened = FALSE;
-
-static int midi_mode;
-static int coarsetune, finetune;
-
-static int xg_mapping = TRUE;
-static int xg_bankmode;
-
-/* effect sensitivity */
-
-#define FX_CUTOFF      0
-#define FX_RESONANCE   1
-#define FX_ATTACK      2
-#define FX_RELEASE     3
-#define FX_VIBRATE     4
-#define FX_VIBDEPTH    5
-#define FX_VIBDELAY    6
-#define FX_NUMS                7
-
-#define DEF_FX_CUTOFF          170
-#define DEF_FX_RESONANCE       6
-#define DEF_FX_ATTACK          50
-#define DEF_FX_RELEASE         50
-#define DEF_FX_VIBRATE         30
-#define DEF_FX_VIBDEPTH                4
-#define DEF_FX_VIBDELAY                1500
-
-/* effect sense: */
-static int gs_sense[] = 
-{
-       DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-       DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-static int xg_sense[] = 
-{
-       DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-       DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-
-
-/* current status */
-static MidiStatus curst;
-
-
-static int
-awe_midi_open (int dev, int mode,
-              void (*input)(int,unsigned char),
-              void (*output)(int))
-{
-       if (midi_opened)
-               return -EBUSY;
-
-       midi_opened = TRUE;
-
-       midi_mode = MODE_GM;
-
-       curst.queue = Q_NONE;
-       curst.qlen = 0;
-       curst.read = 0;
-       curst.status = 0;
-       curst.chan = 0;
-       memset(curst.buf, 0, sizeof(curst.buf));
-
-       init_midi_status(&curst);
-
-       return 0;
-}
-
-static void
-awe_midi_close (int dev)
-{
-       midi_opened = FALSE;
-}
-
-
-static int
-awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-       return -EPERM;
-}
-
-static int
-awe_midi_outputc (int dev, unsigned char midi_byte)
-{
-       if (! midi_opened)
-               return 1;
-
-       /* force to change playing mode */
-       playing_mode = AWE_PLAY_MULTI;
-
-       get_midi_char(&curst, midi_byte);
-       return 1;
-}
-
-
-/*
- * initialize
- */
-
-static void init_midi_status(MidiStatus *st)
-{
-       clear_rpn();
-       coarsetune = 0;
-       finetune = 0;
-}
-
-
-/*
- * RPN & NRPN
- */
-
-#define MAX_MIDI_CHANNELS      16
-
-/* RPN & NRPN */
-static unsigned char nrpn[MAX_MIDI_CHANNELS];  /* current event is NRPN? */
-static int msb_bit;  /* current event is msb for RPN/NRPN */
-/* RPN & NRPN indeces */
-static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
-/* RPN & NRPN values */
-static int rpn_val[MAX_MIDI_CHANNELS];
-
-static void clear_rpn(void)
-{
-       int i;
-       for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
-               nrpn[i] = 0;
-               rpn_msb[i] = 127;
-               rpn_lsb[i] = 127;
-               rpn_val[i] = 0;
-       }
-       msb_bit = 0;
-}
-
-
-/*
- * process midi queue
- */
-
-/* status event types */
-typedef void (*StatusEvent)(MidiStatus *st);
-static struct StatusEventList {
-       StatusEvent process;
-       int qlen;
-} status_event[8] = {
-       {midi_note_off, 2},
-       {midi_note_on, 2},
-       {midi_key_pressure, 2},
-       {midi_control_change, 2},
-       {midi_program_change, 1},
-       {midi_channel_pressure, 1},
-       {midi_pitch_wheel, 2},
-       {NULL, 0},
-};
-
-
-/* read a char from fifo and process it */
-static void get_midi_char(MidiStatus *st, int c)
-{
-       if (c == 0xfe) {
-               /* ignore active sense */
-               st->queue = Q_NONE;
-               return;
-       }
-
-       switch (st->queue) {
-       /* case Q_VARLEN: queue_varlen(st, c); break;*/
-       case Q_READ:
-       case Q_SYSEX:
-               queue_read(st, c);
-               break;
-       case Q_NONE:
-               st->read = 0;
-               if ((c & 0xf0) == 0xf0) {
-                       special_event(st, c);
-               } else if (c & 0x80) { /* status change */
-                       st->status = (c >> 4) & 0x07;
-                       st->chan = c & 0x0f;
-                       st->queue = Q_READ;
-                       st->qlen = status_event[st->status].qlen;
-                       if (st->qlen == 0)
-                               st->queue = Q_NONE;
-               }
-               break;
-       }
-}
-
-/* 0xfx events */
-static void special_event(MidiStatus *st, int c)
-{
-       switch (c) {
-       case 0xf0: /* system exclusive */
-               st->queue = Q_SYSEX;
-               st->qlen = 0;
-               break;
-       case 0xf1: /* MTC quarter frame */
-       case 0xf3: /* song select */
-               st->queue = Q_READ;
-               st->qlen = 1;
-               break;
-       case 0xf2: /* song position */
-               st->queue = Q_READ;
-               st->qlen = 2;
-               break;
-       }
-}
-
-#if 0
-/* read variable length value */
-static void queue_varlen(MidiStatus *st, int c)
-{
-       st->qlen += (c & 0x7f);
-       if (c & 0x80) {
-               st->qlen <<= 7;
-               return;
-       }
-       if (st->qlen <= 0) {
-               st->qlen = 0;
-               st->queue = Q_NONE;
-       }
-       st->queue = Q_READ;
-       st->read = 0;
-}
-#endif
-
-
-/* read a char */
-static void queue_read(MidiStatus *st, int c)
-{
-       if (st->read < MAX_MIDIBUF) {
-               if (st->queue != Q_SYSEX)
-                       c &= 0x7f;
-               st->buf[st->read] = (unsigned char)c;
-       }
-       st->read++;
-       if (st->queue == Q_SYSEX && c == 0xf7) {
-               midi_system_exclusive(st);
-               st->queue = Q_NONE;
-       } else if (st->queue == Q_READ && st->read >= st->qlen) {
-               if (status_event[st->status].process)
-                       status_event[st->status].process(st);
-               st->queue = Q_NONE;
-       }
-}
-
-
-/*
- * status events
- */
-
-/* note on */
-static void midi_note_on(MidiStatus *st)
-{
-       DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-       if (st->buf[1] == 0)
-               midi_note_off(st);
-       else
-               awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* note off */
-static void midi_note_off(MidiStatus *st)
-{
-       DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-       awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* key pressure change */
-static void midi_key_pressure(MidiStatus *st)
-{
-       awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* channel pressure change */
-static void midi_channel_pressure(MidiStatus *st)
-{
-       channels[st->chan].chan_press = st->buf[0];
-       awe_modwheel_change(st->chan, st->buf[0]);
-}
-
-/* pitch wheel change */
-static void midi_pitch_wheel(MidiStatus *st)
-{
-       int val = (int)st->buf[1] * 128 + st->buf[0];
-       awe_bender(0, st->chan, val);
-}
-
-/* program change */
-static void midi_program_change(MidiStatus *st)
-{
-       int preset;
-       preset = st->buf[0];
-       if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
-               preset = 0;
-       else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
-               preset += 64;
-
-       awe_set_instr(0, st->chan, preset);
-}
-
-#define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
-#define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
-#define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
-
-/* midi control change */
-static void midi_control_change(MidiStatus *st)
-{
-       int cmd = st->buf[0];
-       int val = st->buf[1];
-
-       DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
-       if (midi_mode == MODE_XG) {
-               if (xg_control_change(st, cmd, val))
-                       return;
-       }
-
-       /* controls #31 - #64 are LSB of #0 - #31 */
-       msb_bit = 1;
-       if (cmd >= 0x20 && cmd < 0x40) {
-               msb_bit = 0;
-               cmd -= 0x20;
-       }
-
-       switch (cmd) {
-       case CTL_SOFT_PEDAL:
-               if (val == 127)
-                       add_effect(st->chan, AWE_FX_CUTOFF, -160);
-               else
-                       unset_effect(st->chan, AWE_FX_CUTOFF);
-               break;
-
-       case CTL_BANK_SELECT:
-               midi_select_bank(st, val);
-               break;
-               
-       /* set RPN/NRPN parameter */
-       case CTL_REGIST_PARM_NUM_MSB:
-               nrpn[st->chan]=0; rpn_msb[st->chan]=val;
-               break;
-       case CTL_REGIST_PARM_NUM_LSB:
-               nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
-               break;
-       case CTL_NONREG_PARM_NUM_MSB:
-               nrpn[st->chan]=1; rpn_msb[st->chan]=val;
-               break;
-       case CTL_NONREG_PARM_NUM_LSB:
-               nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
-               break;
-
-       /* send RPN/NRPN entry */
-       case CTL_DATA_ENTRY:
-               if (msb_bit)
-                       rpn_val[st->chan] = val * 128;
-               else
-                       rpn_val[st->chan] |= val;
-               if (nrpn[st->chan])
-                       midi_nrpn_event(st);
-               else
-                       midi_rpn_event(st);
-               break;
-
-       /* increase/decrease data entry */
-       case CTL_DATA_INCREMENT:
-               rpn_val[st->chan]++;
-               midi_rpn_event(st);
-               break;
-       case CTL_DATA_DECREMENT:
-               rpn_val[st->chan]--;
-               midi_rpn_event(st);
-               break;
-
-       /* default */
-       default:
-               awe_controller(0, st->chan, cmd, val);
-               break;
-       }
-}
-
-/* tone bank change */
-static void midi_select_bank(MidiStatus *st, int val)
-{
-       if (midi_mode == MODE_XG && msb_bit) {
-               xg_bankmode = val;
-               /* XG MSB value; not normal bank selection */
-               switch (val) {
-               case 127: /* remap to drum channel */
-                       awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
-                       break;
-               default: /* remap to normal channel */
-                       awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-                       break;
-               }
-               return;
-       } else if (midi_mode == MODE_GS && !msb_bit)
-               /* ignore LSB bank in GS mode (used for mapping) */
-               return;
-
-       /* normal bank controls; accept both MSB and LSB */
-       if (! IS_DRUM_CHANNEL(st->chan)) {
-               if (midi_mode == MODE_XG) {
-                       if (xg_bankmode) return;
-                       if (val == 64 || val == 126)
-                               val = 0;
-               } else if (midi_mode == MODE_GS && val == 127)
-                       val = 0;
-               awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-       }
-}
-
-
-/*
- * RPN events
- */
-
-static void midi_rpn_event(MidiStatus *st)
-{
-       int type;
-       type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
-       switch (type) {
-       case 0x0000: /* Pitch bend sensitivity */
-               /* MSB only / 1 semitone per 128 */
-               if (msb_bit) {
-                       channels[st->chan].bender_range = 
-                               rpn_val[st->chan] * 100 / 128;
-               }
-               break;
-                                       
-       case 0x0001: /* fine tuning: */
-               /* MSB/LSB, 8192=center, 100/8192 cent step */
-               finetune = rpn_val[st->chan] - 8192;
-               midi_detune(st->chan, coarsetune, finetune);
-               break;
-
-       case 0x0002: /* coarse tuning */
-               /* MSB only / 8192=center, 1 semitone per 128 */
-               if (msb_bit) {
-                       coarsetune = rpn_val[st->chan] - 8192;
-                       midi_detune(st->chan, coarsetune, finetune);
-               }
-               break;
-
-       case 0x7F7F: /* "lock-in" RPN */
-               break;
-       }
-}
-
-
-/* tuning:
- *   coarse = -8192 to 8192 (100 cent per 128)
- *   fine = -8192 to 8192 (max=100cent)
- */
-static void midi_detune(int chan, int coarse, int fine)
-{
-       /* 4096 = 1200 cents in AWE parameter */
-       int val;
-       val = coarse * 4096 / (12 * 128);
-       val += fine / 24;
-       if (val)
-               send_effect(chan, AWE_FX_INIT_PITCH, val);
-       else
-               unset_effect(chan, AWE_FX_INIT_PITCH);
-}
-
-
-/*
- * system exclusive message
- * GM/GS/XG macros are accepted
- */
-
-static void midi_system_exclusive(MidiStatus *st)
-{
-       /* GM on */
-       static unsigned char gm_on_macro[] = {
-               0x7e,0x7f,0x09,0x01,
-       };
-       /* XG on */
-       static unsigned char xg_on_macro[] = {
-               0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
-       };
-       /* GS prefix
-        * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
-        * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
-        * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
-        */
-       static unsigned char gs_pfx_macro[] = {
-               0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
-       };
-
-#if 0
-       /* SC88 system mode set
-        * single module mode: XX=1
-        * double module mode: XX=0
-        */
-       static unsigned char gs_mode_macro[] = {
-               0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
-       };
-       /* SC88 display macro: XX=01:bitmap, 00:text
-        */
-       static unsigned char gs_disp_macro[] = {
-               0x41,0x10,0x45,0x12,0x10,/*XX,00*/
-       };
-#endif
-
-       /* GM on */
-       if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
-               if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-                       midi_mode = MODE_GM;
-               init_midi_status(st);
-       }
-
-       /* GS macros */
-       else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
-               if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-                       midi_mode = MODE_GS;
-
-               if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
-                       /* GS reset */
-                       init_midi_status(st);
-               }
-
-               else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
-                       /* drum pattern */
-                       int p = st->buf[5] & 0x0f;
-                       if (p == 0) p = 9;
-                       else if (p < 10) p--;
-                       if (st->buf[7] == 0)
-                               DRUM_CHANNEL_OFF(p);
-                       else
-                               DRUM_CHANNEL_ON(p);
-
-               } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
-                       /* program */
-                       int p = st->buf[5] & 0x0f;
-                       if (p == 0) p = 9;
-                       else if (p < 10) p--;
-                       if (! IS_DRUM_CHANNEL(p))
-                               awe_set_instr(0, p, st->buf[7]);
-
-               } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
-                       /* reverb mode */
-                       awe_set_reverb_mode(st->buf[7]);
-
-               } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
-                       /* chorus mode */
-                       awe_set_chorus_mode(st->buf[7]);
-
-               } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
-                       /* master volume */
-                       awe_change_master_volume(st->buf[7]);
-
-               }
-       }
-
-       /* XG on */
-       else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
-               midi_mode = MODE_XG;
-               xg_mapping = TRUE;
-               xg_bankmode = 0;
-       }
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * convert NRPN/control values
- */
-
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-       int i, cval;
-       for (i = 0; i < num_tables; i++) {
-               if (table[i].control == type) {
-                       cval = table[i].convert(val);
-                       send_effect(st->chan, table[i].awe_effect, cval);
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-       int i, cval;
-       for (i = 0; i < num_tables; i++) {
-               if (table[i].control == type) {
-                       cval = table[i].convert(val);
-                       add_effect(st->chan, table[i].awe_effect|0x80, cval);
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-
-/*
- * AWE32 NRPN effects
- */
-
-static unsigned short fx_delay(int val);
-static unsigned short fx_attack(int val);
-static unsigned short fx_hold(int val);
-static unsigned short fx_decay(int val);
-static unsigned short fx_the_value(int val);
-static unsigned short fx_twice_value(int val);
-static unsigned short fx_conv_pitch(int val);
-static unsigned short fx_conv_Q(int val);
-
-/* function for each NRPN */           /* [range]  units */
-#define fx_env1_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_env1_attack fx_attack       /* [0,5940] 1msec */
-#define fx_env1_hold   fx_hold         /* [0,8191] 1msec */
-#define fx_env1_decay  fx_decay        /* [0,5940] 4msec */
-#define fx_env1_release        fx_decay        /* [0,5940] 4msec */
-#define fx_env1_sustain        fx_the_value    /* [0,127] 0.75dB */
-#define fx_env1_pitch  fx_the_value    /* [-127,127] 9.375cents */
-#define fx_env1_cutoff fx_the_value    /* [-127,127] 56.25cents */
-
-#define fx_env2_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_env2_attack fx_attack       /* [0,5940] 1msec */
-#define fx_env2_hold   fx_hold         /* [0,8191] 1msec */
-#define fx_env2_decay  fx_decay        /* [0,5940] 4msec */
-#define fx_env2_release        fx_decay        /* [0,5940] 4msec */
-#define fx_env2_sustain        fx_the_value    /* [0,127] 0.75dB */
-
-#define fx_lfo1_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_lfo1_freq   fx_twice_value  /* [0,127] 84mHz */
-#define fx_lfo1_volume fx_twice_value  /* [0,127] 0.1875dB */
-#define fx_lfo1_pitch  fx_the_value    /* [-127,127] 9.375cents */
-#define fx_lfo1_cutoff fx_twice_value  /* [-64,63] 56.25cents */
-
-#define fx_lfo2_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_lfo2_freq   fx_twice_value  /* [0,127] 84mHz */
-#define fx_lfo2_pitch  fx_the_value    /* [-127,127] 9.375cents */
-
-#define fx_init_pitch  fx_conv_pitch   /* [-8192,8192] cents */
-#define fx_chorus      fx_the_value    /* [0,255] -- */
-#define fx_reverb      fx_the_value    /* [0,255] -- */
-#define fx_cutoff      fx_twice_value  /* [0,127] 62Hz */
-#define fx_filterQ     fx_conv_Q       /* [0,127] -- */
-
-static unsigned short fx_delay(int val)
-{
-       return (unsigned short)calc_parm_delay(val);
-}
-
-static unsigned short fx_attack(int val)
-{
-       return (unsigned short)calc_parm_attack(val);
-}
-
-static unsigned short fx_hold(int val)
-{
-       return (unsigned short)calc_parm_hold(val);
-}
-
-static unsigned short fx_decay(int val)
-{
-       return (unsigned short)calc_parm_decay(val);
-}
-
-static unsigned short fx_the_value(int val)
-{
-       return (unsigned short)(val & 0xff);
-}
-
-static unsigned short fx_twice_value(int val)
-{
-       return (unsigned short)((val * 2) & 0xff);
-}
-
-static unsigned short fx_conv_pitch(int val)
-{
-       return (short)(val * 4096 / 1200);
-}
-
-static unsigned short fx_conv_Q(int val)
-{
-       return (unsigned short)((val / 8) & 0xff);
-}
-
-
-static ConvTable awe_effects[] =
-{
-       { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
-       { 1, AWE_FX_LFO1_FREQ,  fx_lfo1_freq},
-       { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
-       { 3, AWE_FX_LFO2_FREQ,  fx_lfo2_freq},
-
-       { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
-       { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
-       { 6, AWE_FX_ENV1_HOLD,  fx_env1_hold},
-       { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
-       { 8, AWE_FX_ENV1_SUSTAIN,       fx_env1_sustain},
-       { 9, AWE_FX_ENV1_RELEASE,       fx_env1_release},
-
-       {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
-       {11, AWE_FX_ENV2_ATTACK,        fx_env2_attack},
-       {12, AWE_FX_ENV2_HOLD,  fx_env2_hold},
-       {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
-       {14, AWE_FX_ENV2_SUSTAIN,       fx_env2_sustain},
-       {15, AWE_FX_ENV2_RELEASE,       fx_env2_release},
-
-       {16, AWE_FX_INIT_PITCH, fx_init_pitch},
-       {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
-       {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
-       {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
-       {20, AWE_FX_LFO1_VOLUME,        fx_lfo1_volume},
-       {21, AWE_FX_CUTOFF,             fx_cutoff},
-       {22, AWE_FX_FILTERQ,    fx_filterQ},
-       {23, AWE_FX_LFO1_CUTOFF,        fx_lfo1_cutoff},
-       {24, AWE_FX_ENV1_CUTOFF,        fx_env1_cutoff},
-       {25, AWE_FX_CHORUS,             fx_chorus},
-       {26, AWE_FX_REVERB,             fx_reverb},
-};
-
-static int num_awe_effects = numberof(awe_effects);
-
-
-/*
- * GS(SC88) NRPN effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short gs_cutoff(int val)
-{
-       return (val - 64) * gs_sense[FX_CUTOFF] / 50;
-}
-
-/* resonance: 0 to 15(max) */
-static unsigned short gs_filterQ(int val)
-{
-       return (val - 64) * gs_sense[FX_RESONANCE] / 50;
-}
-
-/* attack: */
-static unsigned short gs_attack(int val)
-{
-       return -(val - 64) * gs_sense[FX_ATTACK] / 50;
-}
-
-/* decay: */
-static unsigned short gs_decay(int val)
-{
-       return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* release: */
-static unsigned short gs_release(int val)
-{
-       return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* vibrato freq: 0.042Hz step, max=255 */
-static unsigned short gs_vib_rate(int val)
-{
-       return (val - 64) * gs_sense[FX_VIBRATE] / 50;
-}
-
-/* vibrato depth: max=127, 1 octave */
-static unsigned short gs_vib_depth(int val)
-{
-       return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
-}
-
-/* vibrato delay: -0.725msec step */
-static unsigned short gs_vib_delay(int val)
-{
-       return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
-}
-
-static ConvTable gs_effects[] =
-{
-       {32, AWE_FX_CUTOFF,     gs_cutoff},
-       {33, AWE_FX_FILTERQ,    gs_filterQ},
-       {99, AWE_FX_ENV2_ATTACK, gs_attack},
-       {100, AWE_FX_ENV2_DECAY, gs_decay},
-       {102, AWE_FX_ENV2_RELEASE, gs_release},
-       {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
-       {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
-       {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
-};
-
-static int num_gs_effects = numberof(gs_effects);
-
-
-/*
- * NRPN events: accept as AWE32/SC88 specific controls
- */
-
-static void midi_nrpn_event(MidiStatus *st)
-{
-       if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
-               if (! msb_bit) /* both MSB/LSB necessary */
-                       send_converted_effect(awe_effects, num_awe_effects,
-                                             st, rpn_lsb[st->chan],
-                                             rpn_val[st->chan] - 8192);
-       } else if (rpn_msb[st->chan] == 1) {
-               if (msb_bit) /* only MSB is valid */
-                       add_converted_effect(gs_effects, num_gs_effects,
-                                            st, rpn_lsb[st->chan],
-                                            rpn_val[st->chan] / 128);
-       }
-}
-
-
-/*
- * XG control effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short xg_cutoff(int val)
-{
-       return (val - 64) * xg_sense[FX_CUTOFF] / 64;
-}
-
-/* resonance: 0(open) to 15(most nasal) */
-static unsigned short xg_filterQ(int val)
-{
-       return (val - 64) * xg_sense[FX_RESONANCE] / 64;
-}
-
-/* attack: */
-static unsigned short xg_attack(int val)
-{
-       return -(val - 64) * xg_sense[FX_ATTACK] / 64;
-}
-
-/* release: */
-static unsigned short xg_release(int val)
-{
-       return -(val - 64) * xg_sense[FX_RELEASE] / 64;
-}
-
-static ConvTable xg_effects[] =
-{
-       {71, AWE_FX_CUTOFF,     xg_cutoff},
-       {74, AWE_FX_FILTERQ,    xg_filterQ},
-       {72, AWE_FX_ENV2_RELEASE, xg_release},
-       {73, AWE_FX_ENV2_ATTACK, xg_attack},
-};
-
-static int num_xg_effects = numberof(xg_effects);
-
-static int xg_control_change(MidiStatus *st, int cmd, int val)
-{
-       return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
-}
-
-#endif /* CONFIG_AWE32_MIDIEMU */
-
-
-/*----------------------------------------------------------------*/
-
-
-/*
- * initialization of AWE driver
- */
-
-static void
-awe_initialize(void)
-{
-       DEBUG(0,printk("AWE32: initializing..\n"));
-
-       /* initialize hardware configuration */
-       awe_poke(AWE_HWCF1, 0x0059);
-       awe_poke(AWE_HWCF2, 0x0020);
-
-       /* disable audio; this seems to reduce a clicking noise a bit.. */
-       awe_poke(AWE_HWCF3, 0);
-
-       /* initialize audio channels */
-       awe_init_audio();
-
-       /* initialize DMA */
-       awe_init_dma();
-
-       /* initialize init array */
-       awe_init_array();
-
-       /* check DRAM memory size */
-       awe_check_dram();
-
-       /* initialize the FM section of the AWE32 */
-       awe_init_fm();
-
-       /* set up voice envelopes */
-       awe_tweak();
-
-       /* enable audio */
-       awe_poke(AWE_HWCF3, 0x0004);
-
-       /* set default values */
-       awe_init_ctrl_parms(TRUE);
-
-       /* set equalizer */
-       awe_update_equalizer();
-
-       /* set reverb & chorus modes */
-       awe_update_reverb_mode();
-       awe_update_chorus_mode();
-}
-
-
-/*
- * Core Device Management Functions
- */
-
-/* store values to i/o port array */
-static void setup_ports(int port1, int port2, int port3)
-{
-       awe_ports[0] = port1;
-       if (port2 == 0)
-               port2 = port1 + 0x400;
-       awe_ports[1] = port2;
-       awe_ports[2] = port2 + 2;
-       if (port3 == 0)
-               port3 = port1 + 0x800;
-       awe_ports[3] = port3;
-       awe_ports[4] = port3 + 2;
-
-       port_setuped = TRUE;
-}
-
-/*
- * port request
- *  0x620-623, 0xA20-A23, 0xE20-E23
- */
-
-static int
-awe_request_region(void)
-{
-       if (! port_setuped)
-               return 0;
-       if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
-               return 0;
-       if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
-               goto err_out;
-       if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
-               goto err_out1;
-       return 1;
-err_out1:
-       release_region(awe_ports[1], 4);
-err_out:
-       release_region(awe_ports[0], 4);
-       return 0;
-}
-
-static void
-awe_release_region(void)
-{
-       if (! port_setuped) return;
-       release_region(awe_ports[0], 4);
-       release_region(awe_ports[1], 4);
-       release_region(awe_ports[3], 4);
-}
-
-static int awe_attach_device(void)
-{
-       if (awe_present) return 0; /* for OSS38.. called twice? */
-
-       /* reserve I/O ports for awedrv */
-       if (! awe_request_region()) {
-               printk(KERN_ERR "AWE32: I/O area already used.\n");
-               return 0;
-       }
-
-       /* set buffers to NULL */
-       sfhead = sftail = NULL;
-
-       my_dev = sound_alloc_synthdev();
-       if (my_dev == -1) {
-               printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
-               awe_release_region();
-               return 0;
-       }
-
-       voice_alloc = &awe_operations.alloc;
-       voice_alloc->max_voice = awe_max_voices;
-       synth_devs[my_dev] = &awe_operations;
-
-#ifdef CONFIG_AWE32_MIXER
-       attach_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-       attach_midiemu();
-#endif
-
-       /* clear all samples */
-       awe_reset_samples();
-
-       /* initialize AWE32 hardware */
-       awe_initialize();
-
-       sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
-               AWEDRV_VERSION, memsize/1024);
-       printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
-
-       awe_present = TRUE;
-
-       return 1;
-}
-
-static void awe_dettach_device(void)
-{
-       if (awe_present) {
-               awe_reset_samples();
-               awe_release_region();
-               free_tables();
-#ifdef CONFIG_AWE32_MIXER
-               unload_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-               unload_midiemu();
-#endif
-               sound_unload_synthdev(my_dev);
-               awe_present = FALSE;
-       }
-}
-
-
-/*
- * Legacy device Probing
- */
-
-/* detect emu8000 chip on the specified address; from VV's guide */
-
-static int __init
-awe_detect_base(int addr)
-{
-       setup_ports(addr, 0, 0);
-       if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
-               return 0;
-       if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
-               return 0;
-       if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
-               return 0;
-        DEBUG(0,printk("AWE32 found at %x\n", addr));
-       return 1;
-}
-
-static int __init awe_detect_legacy_devices(void)
-{
-       int base;
-       for (base = 0x620; base <= 0x680; base += 0x20)
-               if (awe_detect_base(base)) {
-                       awe_attach_device();
-                       return 1;
-                       }
-       DEBUG(0,printk("AWE32 Legacy detection failed\n"));
-       return 0;
-}
-
-
-/*
- * PnP device Probing
- */
-
-static struct pnp_device_id awe_pnp_ids[] = {
-       {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
-       {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
-       {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
-       { } /* terminator */
-};
-
-MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
-
-static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
-{
-       int io1, io2, io3;
-
-       if (awe_present) {
-               printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
-       }
-
-       if (!pnp_port_valid(dev,0) ||
-           !pnp_port_valid(dev,1) ||
-           !pnp_port_valid(dev,2)) {
-               printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
-               return -EINVAL;
-       }
-       io1 = pnp_port_start(dev,0);
-       io2 = pnp_port_start(dev,1);
-       io3 = pnp_port_start(dev,2);
-       printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
-              io1, io2, io3);
-       setup_ports(io1, io2, io3);
-
-       awe_attach_device();
-       return 0;
-}
-
-static void awe_pnp_remove(struct pnp_dev *dev)
-{
-       awe_dettach_device();
-}
-
-static struct pnp_driver awe_pnp_driver = {
-       .name           = "AWE32",
-       .id_table       = awe_pnp_ids,
-       .probe          = awe_pnp_probe,
-       .remove         = awe_pnp_remove,
-};
-
-static int __init awe_detect_pnp_devices(void)
-{
-       int ret;
-
-       ret = pnp_register_driver(&awe_pnp_driver);
-       if (ret<0)
-               printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
-       return ret;
-}
-
-
-/*
- * device / lowlevel (module) interface
- */
-
-static int __init
-awe_detect(void)
-{
-       printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
-       if (isapnp) {
-               if (awe_detect_pnp_devices()>=0)
-                       return 1;
-       } else
-               printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
-
-       if (awe_detect_legacy_devices())
-               return 1;
-
-       return 0;
-}
-
-static int __init attach_awe(void)
-{
-       return awe_detect() ? 0 : -ENODEV;
-}
-
-static void __exit unload_awe(void)
-{
-       pnp_unregister_driver(&awe_pnp_driver);
-       awe_dettach_device();
-}
-
-
-module_init(attach_awe);
-module_exit(unload_awe);
-
-#ifndef MODULE
-static int __init setup_awe(char *str)
-{
-       /* io, memsize, isapnp */
-       int ints[4];
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       io = ints[1];
-       memsize = ints[2];
-       isapnp = ints[3];
-
-       return 1;
-}
-
-__setup("awe=", setup_awe);
-#endif
diff --git a/sound/oss/awe_wave.h b/sound/oss/awe_wave.h
deleted file mode 100644 (file)
index a3aa018..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * sound/awe_config.h
- *
- * Configuration of AWE32/SB32/AWE64 wave table synth driver.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-1998 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * chorus & reverb effects send for FM chip: from 0 to 0xff
- * larger numbers often cause weird sounds.
- */
-
-#define DEF_FM_CHORUS_DEPTH    0x10
-#define DEF_FM_REVERB_DEPTH    0x10
-
-
-/*
- * other compile conditions
- */
-
-/* initialize FM passthrough even without extended RAM */
-#undef AWE_ALWAYS_INIT_FM
-
-/* debug on */
-#define AWE_DEBUG_ON
-
-/* GUS compatible mode */
-#define AWE_HAS_GUS_COMPATIBILITY
-
-/* add MIDI emulation by wavetable */
-#define CONFIG_AWE32_MIDIEMU
-
-/* add mixer control of emu8000 equalizer */
-#undef CONFIG_AWE32_MIXER
-
-/* use new volume calculation method as default */
-#define AWE_USE_NEW_VOLUME_CALC
-
-/* check current volume target for searching empty voices */
-#define AWE_CHECK_VTARGET
-
-/* allow sample sharing */
-#define AWE_ALLOW_SAMPLE_SHARING
-
-/*
- * AWE32 card configuration:
- * uncomment the following lines *ONLY* when auto detection doesn't
- * work properly on your machine.
- */
-
-/*#define AWE_DEFAULT_BASE_ADDR        0x620*/ /* base port address */
-/*#define AWE_DEFAULT_MEM_SIZE 512*/   /* kbytes */
-
-/*
- * AWE driver version number
- */
-#define AWE_MAJOR_VERSION      0
-#define AWE_MINOR_VERSION      4
-#define AWE_TINY_VERSION       4
-#define AWE_VERSION_NUMBER     ((AWE_MAJOR_VERSION<<16)|(AWE_MINOR_VERSION<<8)|AWE_TINY_VERSION)
-#define AWEDRV_VERSION         "0.4.4"
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
deleted file mode 100644 (file)
index ea51aaf..0000000
+++ /dev/null
@@ -1,3381 +0,0 @@
-/*
- *      cmpci.c  --  C-Media PCI audio driver.
- *
- *      Copyright (C) 1999  C-media support (support@cmedia.com.tw)
- *
- *      Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *     For update, visit:
- *             http://www.cmedia.com.tw
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi, Jan Pfeifer
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.98   0.1   Initial release
- *    10.05.98   0.2   Fixed many bugs, esp. ADC rate calculation
- *                     First stab at a simple midi interface (no bells&whistles)
- *    13.05.98   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                     set_dac_rate in the FMODE_WRITE case in cm_open
- *                     Fix hwptr out of bounds (now mpg123 works)
- *    14.05.98   0.4   Don't allow excessive interrupt rates
- *    08.06.98   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.98   0.6   Do not include modversions.h
- *                     Now mixer behaviour can basically be selected between
- *                     "OSS documented" and "OSS actual" behaviour
- *    31.08.98   0.7   Fix realplayer problems - dac.count issues
- *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.99   0.10  remove the silly SA_INTERRUPT flag.
- *                     hopefully killed the egcs section type conflict
- *    12.03.99   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                     reported by Johan Maes <joma@telindus.be>
- *    22.03.99   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                     read/write cannot be executed
- *    18.08.99   1.5   Only deallocate DMA buffer when unloading.
- *    02.09.99   1.6   Enable SPDIF LOOP
- *                     Change the mixer read back
- *    21.09.99   2.33  Use RCS version as driver version.
- *                     Add support for modem, S/PDIF loop and 4 channels.
- *                     (8738 only)
- *                     Fix bug cause x11amp cannot play.
- *
- *    Fixes:
- *    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
- *                was calling prog_dmabuf with s->lock held, call missing
- *                unlock_kernel in cm_midi_release
- *    08/10/2001 - use set_current_state in some more places
- *
- *     Carlos Eduardo Gorges <carlos@techlinux.com.br>
- *     Fri May 25 2001
- *     - SMP support ( spin[un]lock* revision )
- *     - speaker mixer support
- *     Mon Aug 13 2001
- *     - optimizations and cleanups
- *
- *    03/01/2003 - open_mode fixes from Georg Acher <acher@in.tum.de>
- *     Simon Braunschmidt <brasimon@web.de>
- *     Sat Jan 31 2004
- *     - provide support for opl3 FM by releasing IO range after initialization
- *
- *    ChenLi Tien <cltien@cmedia.com.tw>
- *    Mar 9 2004
- *     - Fix S/PDIF out if spdif_loop enabled
- *     - Load opl3 driver if enabled (fmio in proper range)
- *     - Load mpu401 if enabled (mpuio in proper range)
- *    Apr 5 2004
- *     - Fix DUAL_DAC dma synchronization bug
- *     - Check exist FM/MPU401 I/O before activate.
- *     - Add AFTM_S16_BE format support, so MPlayer/Xine can play AC3/mutlichannel
- *       on Mac
- *     - Change to support kernel 2.6 so only small patch needed
- *     - All parameters default to 0
- *     - Add spdif_out to send PCM through S/PDIF out jack
- *     - Add hw_copy to get 4-spaker output for general PCM/analog output
- *
- *    Stefan Thater <stefan.thaeter@gmx.de>
- *    Apr 5 2004
- *     - Fix mute single channel for CD/Line-in/AUX-in
- */
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-#include "sound_config.h"
-#include "mpu401.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-#include "opl3.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-#include <linux/gameport.h>
-#include <linux/mutex.h>
-
-#endif
-
-/* --------------------------------------------------------------------- */
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef DMABYTEIO
-#define        DBG(x) {}
-/* --------------------------------------------------------------------- */
-
-#define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
-
-/* CM8338 registers definition ****************/
-
-#define CODEC_CMI_FUNCTRL0             (0x00)
-#define CODEC_CMI_FUNCTRL1             (0x04)
-#define CODEC_CMI_CHFORMAT             (0x08)
-#define CODEC_CMI_INT_HLDCLR           (0x0C)
-#define CODEC_CMI_INT_STATUS           (0x10)
-#define CODEC_CMI_LEGACY_CTRL          (0x14)
-#define CODEC_CMI_MISC_CTRL            (0x18)
-#define CODEC_CMI_TDMA_POS             (0x1C)
-#define CODEC_CMI_MIXER                        (0x20)
-#define CODEC_SB16_DATA                        (0x22)
-#define CODEC_SB16_ADDR                        (0x23)
-#define CODEC_CMI_MIXER1               (0x24)
-#define CODEC_CMI_MIXER2               (0x25)
-#define CODEC_CMI_AUX_VOL              (0x26)
-#define CODEC_CMI_MISC                 (0x27)
-#define CODEC_CMI_AC97                 (0x28)
-
-#define CODEC_CMI_CH0_FRAME1           (0x80)
-#define CODEC_CMI_CH0_FRAME2           (0x84)
-#define CODEC_CMI_CH1_FRAME1           (0x88)
-#define CODEC_CMI_CH1_FRAME2           (0x8C)
-
-#define CODEC_CMI_SPDIF_CTRL           (0x90)
-#define CODEC_CMI_MISC_CTRL2           (0x92)
-
-#define CODEC_CMI_EXT_REG              (0xF0)
-
-/*  Mixer registers for SB16 ******************/
-
-#define DSP_MIX_DATARESETIDX           ((unsigned char)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L         ((unsigned char)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R         ((unsigned char)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L          ((unsigned char)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R          ((unsigned char)(0x33))
-#define DSP_MIX_FMVOLIDX_L             ((unsigned char)(0x34))
-#define DSP_MIX_FMVOLIDX_R             ((unsigned char)(0x35))
-#define DSP_MIX_CDVOLIDX_L             ((unsigned char)(0x36))
-#define DSP_MIX_CDVOLIDX_R             ((unsigned char)(0x37))
-#define DSP_MIX_LINEVOLIDX_L           ((unsigned char)(0x38))
-#define DSP_MIX_LINEVOLIDX_R           ((unsigned char)(0x39))
-
-#define DSP_MIX_MICVOLIDX              ((unsigned char)(0x3A))
-#define DSP_MIX_SPKRVOLIDX             ((unsigned char)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX              ((unsigned char)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L            ((unsigned char)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R            ((unsigned char)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L            ((unsigned char)(0x3F))
-#define DSP_MIX_INGAINIDX_R            ((unsigned char)(0x40))
-#define DSP_MIX_OUTGAINIDX_L           ((unsigned char)(0x41))
-#define DSP_MIX_OUTGAINIDX_R           ((unsigned char)(0x42))
-
-#define DSP_MIX_AGCIDX                 ((unsigned char)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L            ((unsigned char)(0x44))
-#define DSP_MIX_TREBLEIDX_R            ((unsigned char)(0x45))
-#define DSP_MIX_BASSIDX_L              ((unsigned char)(0x46))
-#define DSP_MIX_BASSIDX_R              ((unsigned char)(0x47))
-#define DSP_MIX_EXTENSION              ((unsigned char)(0xf0))
-// pseudo register for AUX
-#define        DSP_MIX_AUXVOL_L                ((unsigned char)(0x50))
-#define        DSP_MIX_AUXVOL_R                ((unsigned char)(0x51))
-
-// I/O length
-#define CM_EXTENT_CODEC          0x100
-#define CM_EXTENT_MIDI   0x2
-#define CM_EXTENT_SYNTH          0x4
-#define CM_EXTENT_GAME   0x8
-
-// Function Control Register 0 (00h)
-#define CHADC0         0x01
-#define CHADC1         0x02
-#define PAUSE0         0x04
-#define PAUSE1         0x08
-
-// Function Control Register 0+2 (02h)
-#define CHEN0          0x01
-#define CHEN1          0x02
-#define RST_CH0                0x04
-#define RST_CH1                0x08
-
-// Function Control Register 1 (04h)
-#define JYSTK_EN       0x02
-#define UART_EN                0x04
-#define        SPDO2DAC        0x40
-#define        SPDFLOOP        0x80
-
-// Function Control Register 1+1 (05h)
-#define        SPDF_0          0x01
-#define        SPDF_1          0x02
-#define        ASFC            0x1c
-#define        DSFC            0xe0
-#define        SPDIF2DAC       (SPDF_1 << 8 | SPDO2DAC)
-
-// Channel Format Register (08h)
-#define CM_CFMT_STEREO 0x01
-#define CM_CFMT_16BIT  0x02
-#define CM_CFMT_MASK   0x03
-#define        POLVALID        0x20
-#define        INVSPDIFI       0x80
-
-// Channel Format Register+2 (0ah)
-#define SPD24SEL       0x20
-
-// Channel Format Register+3 (0bh)
-#define CHB3D          0x20
-#define CHB3D5C                0x80
-
-// Interrupt Hold/Clear Register+2 (0eh)
-#define        CH0_INT_EN      0x01
-#define        CH1_INT_EN      0x02
-
-// Interrupt Register (10h)
-#define CHINT0         0x01
-#define CHINT1         0x02
-#define        CH0BUSY         0x04
-#define        CH1BUSY         0x08
-
-// Legacy Control/Status Register+1 (15h)
-#define        EXBASEN         0x10
-#define        BASE2LIN        0x20
-#define        CENTR2LIN       0x40
-#define        CB2LIN          (BASE2LIN | CENTR2LIN)
-#define        CHB3D6C         0x80
-
-// Legacy Control/Status Register+2 (16h)
-#define        DAC2SPDO        0x20
-#define        SPDCOPYRHT      0x40
-#define        ENSPDOUT        0x80
-
-// Legacy Control/Status Register+3 (17h)
-#define        FMSEL           0x03
-#define        VSBSEL          0x0c
-#define        VMPU            0x60
-#define        NXCHG           0x80
-
-// Miscellaneous Control Register (18h)
-#define        REAR2LIN        0x20
-#define        MUTECH1         0x40
-#define        ENCENTER        0x80
-
-// Miscellaneous Control Register+1 (19h)
-#define        SELSPDIFI2      0x01
-#define        SPDF_AC97       0x80
-
-// Miscellaneous Control Register+2 (1ah)
-#define        AC3_EN          0x04
-#define        FM_EN           0x08
-#define        SPD32SEL        0x20
-#define        XCHGDAC         0x40
-#define        ENDBDAC         0x80
-
-// Miscellaneous Control Register+3 (1bh)
-#define        SPDIFI48K       0x01
-#define        SPDO5V          0x02
-#define        N4SPK3D         0x04
-#define        RESET           0x40
-#define        PWD             0x80
-#define        SPDIF48K        (SPDIFI48K << 24 | SPDF_AC97 << 8)
-
-// Mixer1 (24h)
-#define        CDPLAY          0x01
-#define        X3DEN           0x02
-#define        REAR2FRONT      0x10
-#define        SPK4            0x20
-#define        WSMUTE          0x40
-#define        FMMUTE          0x80
-
-// Miscellaneous Register (27h)
-#define        SPDVALID        0x02
-#define        CENTR2MIC       0x04
-
-// Miscellaneous Register2 (92h)
-#define        SPD32KFMT       0x10
-
-#define CM_CFMT_DACSHIFT   2
-#define CM_CFMT_ADCSHIFT   0
-#define CM_FREQ_DACSHIFT   5
-#define CM_FREQ_ADCSHIFT   2
-#define        RSTDAC  RST_CH1
-#define        RSTADC  RST_CH0
-#define        ENDAC   CHEN1
-#define        ENADC   CHEN0
-#define        PAUSEDAC        PAUSE1
-#define        PAUSEADC        PAUSE0
-#define CODEC_CMI_ADC_FRAME1   CODEC_CMI_CH0_FRAME1
-#define CODEC_CMI_ADC_FRAME2   CODEC_CMI_CH0_FRAME2
-#define CODEC_CMI_DAC_FRAME1   CODEC_CMI_CH1_FRAME1
-#define CODEC_CMI_DAC_FRAME2   CODEC_CMI_CH1_FRAME2
-#define        DACINT  CHINT1
-#define        ADCINT  CHINT0
-#define        DACBUSY CH1BUSY
-#define        ADCBUSY CH0BUSY
-#define        ENDACINT        CH1_INT_EN
-#define        ENADCINT        CH0_INT_EN
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[]   = { 0, 1, 1, 2 };
-
-#define SND_DEV_DSP16   5
-
-#define NR_DEVICE 3            /* maximum number of devices */
-
-#define        set_dac1_rate   set_adc_rate
-#define        set_dac1_rate_unlocked  set_adc_rate_unlocked
-#define        stop_dac1       stop_adc
-#define        stop_dac1_unlocked      stop_adc_unlocked
-#define        get_dmadac1     get_dmaadc
-
-static unsigned int devindex = 0;
-
-//*********************************************/
-
-struct cm_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of cmedia devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       int dev_audio;                  /* soundcore stuff */
-       int dev_mixer;
-
-       unsigned int iosb, iobase, iosynth,
-                        iomidi, iogame, irq;   /* hardware resources */
-       unsigned short deviceid;                /* pci_id */
-
-        struct {                               /* mixer stuff */
-                unsigned int modcnt;
-               unsigned short vol[13];
-        } mix;
-
-       unsigned int rateadc, ratedac;          /* wave stuff */
-       unsigned char fmt, enable;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error;         /* over/underrun */
-               wait_queue_head_t wait;
-
-               unsigned fragsize;      /* redundant, but makes calculations easier */
-               unsigned dmasize;
-               unsigned fragsamples;
-               unsigned dmasamples;
-
-               unsigned mapped:1;      /* OSS stuff */
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       int midi_devc;
-       struct address_info mpu_data;
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-       struct gameport *gameport;
-#endif
-
-       int     chip_version;
-       int     max_channels;
-       int     curr_channels;
-       int     capability;             /* HW capability, various for chip versions */
-
-       int     status;                 /* HW or SW state */
-
-       int     spdif_counter;          /* spdif frame counter */
-};
-
-/* flags used for capability */
-#define        CAN_AC3_HW              0x00000001              /* 037 or later */
-#define        CAN_AC3_SW              0x00000002              /* 033 or later */
-#define        CAN_AC3                 (CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC           0x00000004              /* 033 or later */
-#define        CAN_MULTI_CH_HW         0x00000008              /* 039 or later */
-#define        CAN_MULTI_CH            (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define        CAN_LINE_AS_REAR        0x00000010              /* 033 or later */
-#define        CAN_LINE_AS_BASS        0x00000020              /* 039 or later */
-#define        CAN_MIC_AS_BASS         0x00000040              /* 039 or later */
-
-/* flags used for status */
-#define        DO_AC3_HW               0x00000001
-#define        DO_AC3_SW               0x00000002
-#define        DO_AC3                  (DO_AC3_HW | DO_AC3_SW)
-#define        DO_DUAL_DAC             0x00000004
-#define        DO_MULTI_CH_HW          0x00000008
-#define        DO_MULTI_CH             (DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define        DO_LINE_AS_REAR         0x00000010              /* 033 or later */
-#define        DO_LINE_AS_BASS         0x00000020              /* 039 or later */
-#define        DO_MIC_AS_BASS          0x00000040              /* 039 or later */
-#define        DO_SPDIF_OUT            0x00000100
-#define        DO_SPDIF_IN             0x00000200
-#define        DO_SPDIF_LOOP           0x00000400
-#define        DO_BIGENDIAN_W          0x00001000              /* used in PowerPC */
-#define        DO_BIGENDIAN_R          0x00002000              /* used in PowerPC */
-
-static LIST_HEAD(devs);
-
-static int     mpuio;
-static int     fmio;
-static int     joystick;
-static int     spdif_inverse;
-static int     spdif_loop;
-static int     spdif_out;
-static int     use_line_as_rear;
-static int     use_line_as_bass;
-static int     use_mic_as_bass;
-static int     mic_boost;
-static int     hw_copy;
-module_param(mpuio, int, 0);
-module_param(fmio, int, 0);
-module_param(joystick, bool, 0);
-module_param(spdif_inverse, bool, 0);
-module_param(spdif_loop, bool, 0);
-module_param(spdif_out, bool, 0);
-module_param(use_line_as_rear, bool, 0);
-module_param(use_line_as_bass, bool, 0);
-module_param(use_mic_as_bass, bool, 0);
-module_param(mic_boost, bool, 0);
-module_param(hw_copy, bool, 0);
-MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
-MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
-MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
-MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
-MODULE_PARM_DESC(spdif_out, "(1/0) Send PCM to S/PDIF-out (PCM volume will not function)");
-MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out");
-MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center");
-MODULE_PARM_DESC(use_mic_as_bass, "(1/0) Use mic-in jack as bass/center");
-MODULE_PARM_DESC(mic_boost, "(1/0) Enable microphone boost");
-MODULE_PARM_DESC(hw_copy, "Copy front channel to surround channel");
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned exp=16,l=5,r=0;
-       static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
-
-       /* num: 2, 4, 16, 256, 65536 */
-       /* exp: 1, 2,  4,   8,    16 */
-
-       while(l--) {
-               if( x >= num[l] ) {
-                       if(num[l]>2) x >>= exp;
-                       r+=exp;
-               }
-               exp>>=1;
-       }
-
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outb((inb(addr) & mask) | value, addr);
-}
-
-static void maskw(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outw((inw(addr) & mask) | value, addr);
-}
-
-static void maskl(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outl((inl(addr) & mask) | value, addr);
-}
-
-static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       if (addr)
-           outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC0, 0);
-}
-
-static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CHADC0);
-}
-
-static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       outl(addr, s->iobase + CODEC_CMI_DAC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, 0);
-       if (s->status & DO_DUAL_DAC)
-               set_dmadac1(s, 0, count);
-}
-
-static void set_countadc(struct cm_state *s, unsigned count)
-{
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2 + 2);
-}
-
-static void set_countdac(struct cm_state *s, unsigned count)
-{
-       outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2 + 2);
-       if (s->status & DO_DUAL_DAC)
-           set_countadc(s, count);
-}
-
-static unsigned get_dmadac(struct cm_state *s)
-{
-       unsigned int curr_addr;
-
-       curr_addr = inw(s->iobase + CODEC_CMI_DAC_FRAME2) + 1;
-       curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-       curr_addr = s->dma_dac.dmasize - curr_addr;
-
-       return curr_addr;
-}
-
-static unsigned get_dmaadc(struct cm_state *s)
-{
-       unsigned int curr_addr;
-
-       curr_addr = inw(s->iobase + CODEC_CMI_ADC_FRAME2) + 1;
-       curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
-       curr_addr = s->dma_adc.dmasize - curr_addr;
-
-       return curr_addr;
-}
-
-static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
-{
-       unsigned char regval, pseudo;
-
-       // pseudo register
-       if (idx == DSP_MIX_AUXVOL_L) {
-               data >>= 4;
-               data &= 0x0f;
-               regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0x0f;
-               outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-               return;
-       }
-       if (idx == DSP_MIX_AUXVOL_R) {
-               data &= 0xf0;
-               regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0xf0;
-               outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-               return;
-       }
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       // pseudo bits
-       if (idx == DSP_MIX_OUTMIXIDX) {
-               pseudo = data & ~0x1f;
-               pseudo >>= 1;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x30;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_L) {
-               pseudo = data & 0x80;
-               pseudo >>= 1;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x40;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_R) {
-               pseudo = data & 0x80;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x80;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       outb(data, s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-}
-
-static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
-{
-       unsigned char v, pseudo;
-
-       // pseudo register
-       if (idx == DSP_MIX_AUXVOL_L) {
-               v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0x0f;
-               v <<= 4;
-               return v;
-       }
-       if (idx == DSP_MIX_AUXVOL_L) {
-               v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0xf0;
-               return v;
-       }
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       v = inb(s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-       // pseudo bits
-       if (idx == DSP_MIX_OUTMIXIDX) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x30;
-               pseudo <<= 1;
-               v |= pseudo;
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_L) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x40;
-               pseudo <<= 1;
-               v |= pseudo;
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_R) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x80;
-               v |= pseudo;
-       }
-       return v;
-}
-
-static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-       if (mask && s->chip_version > 0) {      /* 8338 cannot keep this */
-               s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
-               udelay(10);
-       }
-       s->fmt = (s->fmt & mask) | data;
-       outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
-       udelay(10);
-}
-
-static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_fmt_unlocked(s,mask,data);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-}
-
-static struct {
-       unsigned        rate;
-       unsigned        lower;
-       unsigned        upper;
-       unsigned char   freq;
-} rate_lookup[] =
-{
-       { 5512,         (0 + 5512) / 2,         (5512 + 8000) / 2,      0 },
-       { 8000,         (5512 + 8000) / 2,      (8000 + 11025) / 2,     4 },
-       { 11025,        (8000 + 11025) / 2,     (11025 + 16000) / 2,    1 },
-       { 16000,        (11025 + 16000) / 2,    (16000 + 22050) / 2,    5 },
-       { 22050,        (16000 + 22050) / 2,    (22050 + 32000) / 2,    2 },
-       { 32000,        (22050 + 32000) / 2,    (32000 + 44100) / 2,    6 },
-       { 44100,        (32000 + 44100) / 2,    (44100 + 48000) / 2,    3 },
-       { 48000,        (44100 + 48000) / 2,    48000,                  7 }
-};
-
-static void set_spdif_copyright(struct cm_state *s, int spdif_copyright)
-{
-       /* enable SPDIF-in Copyright */
-       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~SPDCOPYRHT, spdif_copyright ? SPDCOPYRHT : 0);
-}
-
-static void set_spdif_loop(struct cm_state *s, int spdif_loop)
-{
-       /* enable SPDIF loop */
-       if (spdif_loop) {
-               s->status |= DO_SPDIF_LOOP;
-               /* turn on spdif-in to spdif-out */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, SPDFLOOP);
-       } else {
-               s->status &= ~DO_SPDIF_LOOP;
-               /* turn off spdif-in to spdif-out */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDFLOOP, 0);
-       }
-}
-
-static void set_spdif_monitor(struct cm_state *s, int channel)
-{
-       // SPDO2DAC
-       maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDO2DAC, channel == 2 ? SPDO2DAC : 0);
-       // CDPLAY
-       if (s->chip_version >= 39)
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, channel ? CDPLAY : 0);
-}
-
-static void set_spdifout_level(struct cm_state *s, int level5v)
-{
-       /* SPDO5V */
-       if (s->chip_version > 0)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~SPDO5V, level5v ? SPDO5V : 0);
-}
-
-static void set_spdifin_inverse(struct cm_state *s, int spdif_inverse)
-{
-       if (s->chip_version == 0)       /* 8338 has not this feature */
-               return;
-       if (spdif_inverse) {
-               /* turn on spdif-in inverse */
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT, ~0, INVSPDIFI);
-               else
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
-       } else {
-               /* turn off spdif-ininverse */
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT, ~INVSPDIFI, 0);
-               else
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
-       }
-}
-
-static void set_spdifin_channel2(struct cm_state *s, int channel2)
-{
-       /* SELSPDIFI2 */
-       if (s->chip_version >= 39)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 1, ~SELSPDIFI2, channel2 ? SELSPDIFI2 : 0);
-}
-
-static void set_spdifin_valid(struct cm_state *s, int valid)
-{
-       /* SPDVALID */
-       maskb(s->iobase + CODEC_CMI_MISC, ~SPDVALID, valid ? SPDVALID : 0);
-}
-
-static void set_spdifout_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (rate != 48000 && rate != 44100)
-               rate = 0;
-       if (rate == 48000 || rate == 44100) {
-               set_spdif_loop(s, 0);
-               // SPDF_1
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-               // SPDIFI48K SPDF_AC97
-               maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-               if (s->chip_version >= 55)
-               // SPD32KFMT
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL2, ~SPD32KFMT, rate == 48000 ? SPD32KFMT : 0);
-               if (s->chip_version > 0)
-               // ENSPDOUT
-                       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, ENSPDOUT);
-               // monitor SPDIF out
-               set_spdif_monitor(s, 2);
-               s->status |= DO_SPDIF_OUT;
-       } else {
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~ENSPDOUT, 0);
-               // monitor none
-               set_spdif_monitor(s, 0);
-               s->status &= ~DO_SPDIF_OUT;
-       }
-}
-
-static void set_spdifout(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifout_unlocked(s,rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_spdifin_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (rate == 48000 || rate == 44100) {
-               // SPDF_1
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-               // SPDIFI48K SPDF_AC97
-               maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-               s->status |= DO_SPDIF_IN;
-       } else {
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-               s->status &= ~DO_SPDIF_IN;
-       }
-}
-
-static void set_spdifin(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifin_unlocked(s,rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* find parity for bit 4~30 */
-static unsigned parity(unsigned data)
-{
-       unsigned parity = 0;
-       int counter = 4;
-
-       data >>= 4;     // start from bit 4
-       while (counter <= 30) {
-               if (data & 1)
-                       parity++;
-               data >>= 1;
-               counter++;
-       }
-       return parity & 1;
-}
-
-static void set_ac3_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (!(s->capability & CAN_AC3))
-               return;
-       /* enable AC3 */
-       if (rate && rate != 44100)
-               rate = 48000;
-       if (rate == 48000 || rate == 44100) {
-               // mute DAC
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, WSMUTE);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0, MUTECH1);
-               // AC3EN for 039, 0x04
-               if (s->chip_version >= 39) {
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, AC3_EN);
-                       if (s->chip_version == 55)
-                               maskb(s->iobase + CODEC_CMI_SPDIF_CTRL, ~2, 0);
-               // AC3EN for 037, 0x10
-               } else if (s->chip_version == 37)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10);
-               if (s->capability & CAN_AC3_HW) {
-                       // SPD24SEL for 039, 0x20, but cannot be set
-                       if (s->chip_version == 39)
-                               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, SPD24SEL);
-                       // SPD24SEL for 037, 0x02
-                       else if (s->chip_version == 37)
-                               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02);
-                       if (s->chip_version >= 39)
-                               maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, 0);
-
-                       s->status |= DO_AC3_HW;
-                } else {
-                       // SPD32SEL for 037 & 039
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, SPD32SEL);
-                       // set 176K sample rate to fix 033 HW bug
-                       if (s->chip_version == 33) {
-                               if (rate == 48000)
-                                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08);
-                               else
-                                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-                       }
-                       s->status |= DO_AC3_SW;
-               }
-       } else {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~WSMUTE, 0);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~MUTECH1, 0);
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~(SPD24SEL|0x12), 0);
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~(SPD32SEL|AC3_EN), 0);
-               if (s->chip_version == 33)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MIXER1, ~0, CDPLAY);
-               s->status &= ~DO_AC3;
-       }
-       s->spdif_counter = 0;
-}
-
-static void set_line_as_rear(struct cm_state *s, int use_line_as_rear)
-{
-       if (!(s->capability & CAN_LINE_AS_REAR))
-               return;
-       if (use_line_as_rear) {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, SPK4);
-               s->status |= DO_LINE_AS_REAR;
-       } else {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~SPK4, 0);
-               s->status &= ~DO_LINE_AS_REAR;
-       }
-}
-
-static void set_line_as_bass(struct cm_state *s, int use_line_as_bass)
-{
-       if (!(s->capability & CAN_LINE_AS_BASS))
-               return;
-       if (use_line_as_bass) {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, CB2LIN);
-               s->status |= DO_LINE_AS_BASS;
-       } else {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CB2LIN, 0);
-               s->status &= ~DO_LINE_AS_BASS;
-       }
-}
-
-static void set_mic_as_bass(struct cm_state *s, int use_mic_as_bass)
-{
-       if (!(s->capability & CAN_MIC_AS_BASS))
-               return;
-       if (use_mic_as_bass) {
-               maskb(s->iobase + CODEC_CMI_MISC, ~0, 0x04);
-               s->status |= DO_MIC_AS_BASS;
-       } else {
-               maskb(s->iobase + CODEC_CMI_MISC, ~0x04, 0);
-               s->status &= ~DO_MIC_AS_BASS;
-       }
-}
-
-static void set_hw_copy(struct cm_state *s, int hw_copy)
-{
-       if (s->max_channels > 2 && hw_copy)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, N4SPK3D);
-       else
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~N4SPK3D, 0);
-}
-
-static void set_ac3(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifout_unlocked(s, rate);
-       set_ac3_unlocked(s, rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int trans_ac3(struct cm_state *s, void *dest, const char __user *source, int size)
-{
-       int   i = size / 2;
-       unsigned long data;
-       unsigned short data16;
-       unsigned long *dst = (unsigned long *) dest;
-       unsigned short __user *src = (unsigned short __user *)source;
-       int err;
-
-       do {
-               if ((err = __get_user(data16, src++)))
-                       return err;
-               data = (unsigned long)le16_to_cpu(data16);
-               data <<= 12;                    // ok for 16-bit data
-               if (s->spdif_counter == 2 || s->spdif_counter == 3)
-                       data |= 0x40000000;     // indicate AC-3 raw data
-               if (parity(data))
-                       data |= 0x80000000;     // parity
-               if (s->spdif_counter == 0)
-                       data |= 3;              // preamble 'M'
-               else if (s->spdif_counter & 1)
-                       data |= 5;              // odd, 'W'
-               else
-                       data |= 9;              // even, 'M'
-               *dst++ = cpu_to_le32(data);
-               s->spdif_counter++;
-               if (s->spdif_counter == 384)
-                       s->spdif_counter = 0;
-       } while (--i);
-
-       return 0;
-}
-
-static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
-{
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->rateadc = rate;
-       freq <<= CM_FREQ_ADCSHIFT;
-
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-}
-
-static void set_adc_rate(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->rateadc = rate;
-       freq <<= CM_FREQ_ADCSHIFT;
-
-       spin_lock_irqsave(&s->lock, flags);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac_rate(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->ratedac = rate;
-       freq <<= CM_FREQ_DACSHIFT;
-
-       spin_lock_irqsave(&s->lock, flags);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~DSFC, freq);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       if (s->curr_channels <= 2 && spdif_out)
-               set_spdifout(s, rate);
-       if (s->status & DO_DUAL_DAC)
-               set_dac1_rate(s, rate);
-}
-
-/* --------------------------------------------------------------------- */
-static inline void reset_adc(struct cm_state *s)
-{
-       /* reset bus master */
-       outb(s->enable | RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       udelay(10);
-       outb(s->enable & ~RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-}
-
-static inline void reset_dac(struct cm_state *s)
-{
-       /* reset bus master */
-       outb(s->enable | RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       udelay(10);
-       outb(s->enable & ~RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       if (s->status & DO_DUAL_DAC)
-               reset_adc(s);
-}
-
-static inline void pause_adc(struct cm_state *s)
-{
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEADC);
-}
-
-static inline void pause_dac(struct cm_state *s)
-{
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEDAC);
-       if (s->status & DO_DUAL_DAC)
-               pause_adc(s);
-}
-
-static inline void disable_adc(struct cm_state *s)
-{
-       /* disable channel */
-       s->enable &= ~ENADC;
-       outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       reset_adc(s);
-}
-
-static inline void disable_dac(struct cm_state *s)
-{
-       /* disable channel */
-       s->enable &= ~ENDAC;
-       outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       reset_dac(s);
-       if (s->status & DO_DUAL_DAC)
-               disable_adc(s);
-}
-
-static inline void enable_adc(struct cm_state *s)
-{
-       if (!(s->enable & ENADC)) {
-               /* enable channel */
-               s->enable |= ENADC;
-               outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       }
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEADC, 0);
-}
-
-static inline void enable_dac_unlocked(struct cm_state *s)
-{
-       if (!(s->enable & ENDAC)) {
-               /* enable channel */
-               s->enable |= ENDAC;
-               outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       }
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEDAC, 0);
-
-       if (s->status & DO_DUAL_DAC)
-               enable_adc(s);
-}
-
-static inline void stop_adc_unlocked(struct cm_state *s)
-{
-       if (s->enable & ENADC) {
-               /* disable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENADCINT, 0);
-               disable_adc(s);
-       }
-}
-
-static inline void stop_adc(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       stop_adc_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-}
-
-static inline void stop_dac_unlocked(struct cm_state *s)
-{
-       if (s->enable & ENDAC) {
-               /* disable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENDACINT, 0);
-               disable_dac(s);
-       }
-       if (s->status & DO_DUAL_DAC)
-               stop_dac1_unlocked(s);
-}
-
-static inline void stop_dac(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       stop_dac_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static inline void start_adc_unlocked(struct cm_state *s)
-{
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
-               enable_adc(s);
-       }
-}
-
-static void start_adc(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       start_adc_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac1_unlocked(struct cm_state *s)
-{
-       if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
-               enable_dac_unlocked(s);
-       }
-}
-
-static void start_dac_unlocked(struct cm_state *s)
-{
-       if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENDACINT);
-               enable_dac_unlocked(s);
-       }
-       if (s->status & DO_DUAL_DAC)
-               start_dac1_unlocked(s);
-}
-
-static void start_dac(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       start_dac_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec);
-
-static int set_dac_channels(struct cm_state *s, int channels)
-{
-       unsigned long flags;
-       static unsigned int fmmute = 0;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       if ((channels > 2) && (channels <= s->max_channels)
-        && (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) {
-           set_spdifout_unlocked(s, 0);
-           if (s->capability & CAN_MULTI_CH_HW) {
-               // NXCHG
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, NXCHG);
-               // CHB3D or CHB3D5C
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), channels > 4 ? CHB3D5C : CHB3D);
-               // CHB3D6C
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, channels == 6 ? CHB3D6C : 0);
-               // ENCENTER
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~ENCENTER, channels == 6 ? ENCENTER : 0);
-               s->status |= DO_MULTI_CH_HW;
-           } else if (s->capability & CAN_DUAL_DAC) {
-               unsigned char fmtm = ~0, fmts = 0;
-               ssize_t ret;
-
-               // ENDBDAC, turn on double DAC mode
-               // XCHGDAC, CH0 -> back, CH1->front
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, ENDBDAC|XCHGDAC);
-               // mute FM
-               fmmute = inb(s->iobase + CODEC_CMI_MIXER1) & FMMUTE;
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, FMMUTE);
-               s->status |= DO_DUAL_DAC;
-               // prepare secondary buffer
-               spin_unlock_irqrestore(&s->lock, flags);
-               ret = prog_dmabuf(s, 1);
-               if (ret) return ret;
-               spin_lock_irqsave(&s->lock, flags);
-
-               // copy the hw state
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-               // the HW only support 16-bit stereo
-               fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-               fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-               fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-               fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-
-               set_fmt_unlocked(s, fmtm, fmts);
-               set_adc_rate_unlocked(s, s->ratedac);
-           }
-           // disable 4 speaker mode (analog duplicate)
-           set_hw_copy(s, 0);
-           s->curr_channels = channels;
-
-           // enable jack redirect
-           set_line_as_rear(s, use_line_as_rear);
-           if (channels > 4) {
-                   set_line_as_bass(s, use_line_as_bass);
-                   set_mic_as_bass(s, use_mic_as_bass);
-           }
-       } else {
-           if (s->status & DO_MULTI_CH_HW) {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~NXCHG, 0);
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), 0);
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, 0);
-           } else if (s->status & DO_DUAL_DAC) {
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~ENDBDAC, 0);
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~FMMUTE, fmmute);
-           }
-           // enable 4 speaker mode (analog duplicate)
-           set_hw_copy(s, hw_copy);
-           s->status &= ~DO_MULTI_CH;
-           s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-           // disable jack redirect
-           set_line_as_rear(s, hw_copy ? use_line_as_rear : 0);
-           set_line_as_bass(s, 0);
-           set_mic_as_bass(s, 0);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return s->curr_channels;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct cm_state *s, struct dmabuf *db)
-{
-       struct page *pstart, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-                       ClearPageReserved(pstart);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-/* Ch1 is used for playback, Ch0 is used for recording */
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *pstart, *pend;
-       unsigned char fmt;
-       unsigned long flags;
-
-       fmt = s->fmt;
-       if (rec) {
-               stop_adc(s);
-               fmt >>= CM_CFMT_ADCSHIFT;
-       } else {
-               stop_dac(s);
-               fmt >>= CM_CFMT_DACSHIFT;
-       }
-
-       fmt &= CM_CFMT_MASK;
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf || !db->dmaaddr)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-                       SetPageReserved(pstart);
-       }
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       /* to make fragsize >= 4096 */
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       db->dmasamples = db->dmasize >> sample_shift[fmt];
-       memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) {
-               if (s->status & DO_DUAL_DAC)
-                   set_dmadac1(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               else
-                   set_dmaadc(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               /* program sample counts */
-               set_countdac(s, db->fragsamples);
-       } else {
-               set_dmadac(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               /* program sample counts */
-               set_countdac(s, db->fragsamples);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(struct cm_state *s)
-{
-       unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80;
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned char *buf1 = s->dma_adc.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               if (s->status & DO_DUAL_DAC)
-                       memset(buf1 + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-       if (s->status & DO_DUAL_DAC)
-               memset(buf1 + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void cm_update_ptr(struct cm_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-           if (s->status & DO_DUAL_DAC) {
-                   /* the dac part will finish for this */
-           } else {
-               hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               pause_adc(s);
-                               s->dma_adc.error++;
-                       }
-               }
-           }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = get_dmadac(s) % s->dma_dac.dmasize;
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->status & DO_DUAL_DAC) {
-                       s->dma_adc.hwptr = hwptr;
-                       s->dma_adc.total_bytes += diff;
-               }
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               pause_dac(s);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                               if (s->status & DO_DUAL_DAC)
-                                       s->dma_adc.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-static irqreturn_t cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct cm_state *s = (struct cm_state *)dev_id;
-       unsigned int intsrc, intstat;
-       unsigned char mask = 0;
-
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
-       if (!(intsrc & 0x80000000))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       /* acknowledge interrupt */
-       if (intsrc & ADCINT)
-               mask |= ENADCINT;
-       if (intsrc & DACINT)
-               mask |= ENDACINT;
-       outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       cm_update_ptr(s);
-       spin_unlock(&s->lock);
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       if (intsrc & 0x00010000) {      // UART interrupt
-               if (s->midi_devc && intchk_mpu401((void *)s->midi_devc))
-                       mpuintr(irq, (void *)s->midi_devc, regs);
-               else
-                       inb(s->iomidi);// dummy read
-       }
-#endif
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != CM_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-#define MT_5MUTEMONO  5
-
-static const struct {
-       unsigned left;
-       unsigned right;
-       unsigned type;
-       unsigned rec;
-       unsigned play;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_CD]     = { DSP_MIX_CDVOLIDX_L,     DSP_MIX_CDVOLIDX_R,     MT_5MUTE,     0x04, 0x06 },
-       [SOUND_MIXER_LINE]   = { DSP_MIX_LINEVOLIDX_L,   DSP_MIX_LINEVOLIDX_R,   MT_5MUTE,     0x10, 0x18 },
-       [SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      DSP_MIX_MICVOLIDX,      MT_5MUTEMONO, 0x01, 0x01 },
-       [SOUND_MIXER_SYNTH]  = { DSP_MIX_FMVOLIDX_L,     DSP_MIX_FMVOLIDX_R,     MT_5MUTE,     0x40, 0x00 },
-       [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,     0x00, 0x00 },
-       [SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 },
-       [SOUND_MIXER_LINE1]  = { DSP_MIX_AUXVOL_L,       DSP_MIX_AUXVOL_R,       MT_5MUTE,     0x80, 0x60 },
-       [SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,     DSP_MIX_SPKRVOLIDX,     MT_5MUTEMONO, 0x00, 0x01 }
-};
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
-{
-       [SOUND_MIXER_CD]     = 1,
-       [SOUND_MIXER_LINE]   = 2,
-       [SOUND_MIXER_MIC]    = 3,
-       [SOUND_MIXER_SYNTH]  = 4,
-       [SOUND_MIXER_VOLUME] = 5,
-       [SOUND_MIXER_PCM]    = 6,
-       [SOUND_MIXER_LINE1]  = 7,
-       [SOUND_MIXER_SPEAKER]= 8
-};
-
-static unsigned mixer_outmask(struct cm_state *s)
-{
-       unsigned long flags;
-       int i, j, k;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdmixer(s, DSP_MIX_OUTMIXIDX);
-       spin_unlock_irqrestore(&s->lock, flags);
-       for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-               if (j & mixtable[i].play)
-                       k |= 1 << i;
-       return k;
-}
-
-static unsigned mixer_recmask(struct cm_state *s)
-{
-       unsigned long flags;
-       int i, j, k;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
-       spin_unlock_irqrestore(&s->lock, flags);
-       for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-               if (j & mixtable[i].rec)
-                       k |= 1 << i;
-       return k;
-}
-
-static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val, j;
-       unsigned char l, r, rl, rr;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "cmpci", sizeof(info.id));
-               strlcpy(info.name, "C-Media PCI", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "cmpci", sizeof(info.id));
-               strlcpy(info.name, "C-Media cmpci", sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       val = mixer_recmask(s);
-                       return put_user(val, p);
-
-                case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-                       val = mixer_outmask(s);
-                       return put_user(val, p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].rec)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].play)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_CAPS:
-                       return put_user(0, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-                       if (!volidx[i])
-                               return -EINVAL;
-                       return put_user(s->mix.vol[volidx[i]-1], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               i = hweight32(val);
-               for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (!mixtable[i].rec) {
-                               val &= ~(1 << i);
-                               continue;
-                       }
-                       j |= mixtable[i].rec;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
-               wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1) | (j & 0x80));
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (!mixtable[i].play) {
-                               val &= ~(1 << i);
-                               continue;
-                       }
-                       j |= mixtable[i].play;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               wrmixer(s, DSP_MIX_OUTMIXIDX, j);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               r = (val >> 8) & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (r > 100)
-                       r = 100;
-               spin_lock_irqsave(&s->lock, flags);
-               switch (mixtable[i].type) {
-               case MT_4:
-                       if (l >= 10)
-                               l -= 10;
-                       if (r >= 10)
-                               r -= 10;
-                       frobindir(s, mixtable[i].left, 0xf0, l / 6);
-                       frobindir(s, mixtable[i].right, 0xf0, l / 6);
-                       break;
-
-               case MT_4MUTEMONO:
-                       rl = (l < 4 ? 0 : (l - 5) / 3) & 31;
-                       rr = (rl >> 2) & 7;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       if (i == SOUND_MIXER_MIC)
-                               maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-                       break;
-
-               case MT_5MUTEMONO:
-                       rl = l < 4 ? 0 : (l - 5) / 3;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       l = rdmixer(s, DSP_MIX_OUTMIXIDX) & ~mixtable[i].play;
-                       r = rl ? mixtable[i].play : 0;
-                       wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-                       /* for recording */
-                       if (i == SOUND_MIXER_MIC) {
-                               if (s->chip_version >= 37) {
-                                       rr = rl >> 1;
-                                       maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, (rr&0x07)<<1);
-                                       frobindir(s, DSP_MIX_EXTENSION, ~0x01, rr>>3);
-                               } else {
-                                       rr = rl >> 2;
-                                       maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-                               }
-                       }
-                       break;
-
-               case MT_5MUTE:
-                       rl = l < 4 ? 0 : (l - 5) / 3;
-                       rr = r < 4 ? 0 : (r - 5) / 3;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       wrmixer(s, mixtable[i].right, rr<<3);
-                       l = rdmixer(s, DSP_MIX_OUTMIXIDX);
-                       l &= ~mixtable[i].play;
-                       r = (rl|rr) ? mixtable[i].play : 0;
-                       wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-                       break;
-
-               case MT_6MUTE:
-                       if (l < 6)
-                               rl = 0x00;
-                       else
-                               rl = l * 2 / 3;
-                       if (r < 6)
-                               rr = 0x00;
-                       else
-                               rr = r * 2 / 3;
-                       wrmixer(s, mixtable[i].left, rl);
-                       wrmixer(s, mixtable[i].right, rr);
-                       break;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (!volidx[i])
-                       return -EINVAL;
-               s->mix.vol[volidx[i]-1] = val;
-               return put_user(s->mix.vol[volidx[i]-1], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int cm_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct cm_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct cm_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int cm_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations cm_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = cm_ioctl_mixdev,
-       .open    = cm_open_mixdev,
-       .release = cm_release_mixdev,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct cm_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "cmpci: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t cm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-        add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_adc_unlocked(s);
-                               set_dmaadc(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-                               /* program sample counts */
-                               set_countadc(s, s->dma_adc.fragsamples);
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (s->status & DO_BIGENDIAN_R) {
-                       int     i, err;
-                       unsigned char *src;
-                       char __user *dst = buffer;
-                       unsigned char data[2];
-
-                       src = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 2; i++) {
-                               data[0] = src[1];
-                               data[1] = src[0];
-                               if ((err = __put_user(data[0], dst++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __put_user(data[1], dst++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               src += 2;
-                       }
-               } else if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc_unlocked(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-out:
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t cm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (s->status & DO_DUAL_DAC) {
-               if (s->dma_adc.mapped)
-                       return -ENXIO;
-               if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                       return ret;
-       }
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-        add_wait_queue(&s->dma_dac.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               if (s->status & DO_DUAL_DAC) {
-                       s->dma_adc.swptr = s->dma_dac.swptr;
-                       s->dma_adc.count = s->dma_dac.count;
-                       s->dma_adc.endcleared = s->dma_dac.endcleared;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->status & DO_AC3_SW) {
-                       if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize)
-                               cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2;
-               } else {
-                       if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                               cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               }
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if ((s->status & DO_DUAL_DAC) && (cnt > count / 2))
-                   cnt = count / 2;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_dac_unlocked(s);
-                               set_dmadac(s, s->dma_dac.dmaaddr, s->dma_dac.dmasamples);
-                               /* program sample counts */
-                               set_countdac(s, s->dma_dac.fragsamples);
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               if (s->status & DO_DUAL_DAC)  {
-                                       set_dmadac1(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-                                       s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               }
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (s->status & DO_AC3_SW) {
-                       int err;
-
-                       // clip exceeded data, caught by 033 and 037
-                       if (swptr + 2 * cnt > s->dma_dac.dmasize)
-                               cnt = (s->dma_dac.dmasize - swptr) / 2;
-                       if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt))) {
-                               ret = err;
-                               goto out;
-                       }
-                       swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
-               } else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) {
-                       int     i, err;
-                       const char __user *src = buffer;
-                       unsigned char *dst0, *dst1;
-                       unsigned char data[8];
-
-                       dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-                       dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 4; i++) {
-                               if ((err = __get_user(data[0], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[1], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[2], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[3], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[4], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[5], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[6], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[7], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               dst0[0] = data[1];
-                               dst0[1] = data[0];
-                               dst0[2] = data[3];
-                               dst0[3] = data[2];
-                               dst1[0] = data[5];
-                               dst1[1] = data[4];
-                               dst1[2] = data[7];
-                               dst1[3] = data[6];
-                               dst0 += 4;
-                               dst1 += 4;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else if (s->status & DO_DUAL_DAC) {
-                       int     i, err;
-                       unsigned long __user *src = (unsigned long __user *) buffer;
-                       unsigned long *dst0, *dst1;
-
-                       dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
-                       dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 4; i++) {
-                               if ((err = __get_user(*dst0++, src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(*dst1++, src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else if (s->status & DO_BIGENDIAN_W) {
-                       int     i, err;
-                       const char __user *src = buffer;
-                       unsigned char *dst;
-                       unsigned char data[2];
-
-                       dst = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-                       // swap hi/lo bytes for each sample
-                       for (i = 0; i < cnt / 2; i++) {
-                               if ((err = __get_user(data[0], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[1], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               dst[0] = data[1];
-                               dst[1] = data[0];
-                               dst += 2;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else {
-                       if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               goto out;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               if (s->status & DO_AC3_SW)
-                       s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->status & DO_DUAL_DAC) {
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-               }
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-out:
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 0))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       cm_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int cm_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-#define SNDCTL_SPDIF_COPYRIGHT _SIOW('S',  0, int)       // set/reset S/PDIF copy protection
-#define SNDCTL_SPDIF_LOOP      _SIOW('S',  1, int)       // set/reset S/PDIF loop
-#define SNDCTL_SPDIF_MONITOR   _SIOW('S',  2, int)       // set S/PDIF monitor
-#define SNDCTL_SPDIF_LEVEL     _SIOW('S',  3, int)       // set/reset S/PDIF out level
-#define SNDCTL_SPDIF_INV       _SIOW('S',  4, int)       // set/reset S/PDIF in inverse
-#define SNDCTL_SPDIF_SEL2      _SIOW('S',  5, int)       // set S/PDIF in #2
-#define SNDCTL_SPDIF_VALID     _SIOW('S',  6, int)       // set S/PDIF valid
-#define SNDCTL_SPDIFOUT                _SIOW('S',  7, int)       // set S/PDIF out
-#define SNDCTL_SPDIFIN         _SIOW('S',  8, int)       // set S/PDIF out
-
-static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, p);
-
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_adc_unlocked(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate_unlocked(s, val);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (s->status & DO_DUAL_DAC)
-                                       s->dma_adc.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                       else
-                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                       else
-                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-                       if (s->status & DO_DUAL_DAC) {
-                               s->dma_adc.ready = 0;
-                               if (val)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                       }
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-                               if (s->status & DO_DUAL_DAC) {
-                                       s->dma_adc.ready = 0;
-                                       if (val >= 2)
-                                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                                       else
-                                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                               }
-                       }
-                       set_fmt(s, fmtm, fmtd);
-                       if ((s->capability & CAN_MULTI_CH)
-                            && (file->f_mode & FMODE_WRITE)) {
-                               val = set_dac_channels(s, val);
-                               return put_user(val, p);
-                       }
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
-                                          : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_BE|AFMT_S16_LE|AFMT_U8|
-                       ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-                                       fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
-                               if (val == AFMT_S16_BE)
-                                       s->status |= DO_BIGENDIAN_R;
-                               else
-                                       s->status &= ~DO_BIGENDIAN_R;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_BE || val == AFMT_S16_LE || val == AFMT_AC3)
-                                       fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
-                               if (val == AFMT_AC3) {
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                                       set_ac3(s, 48000);
-                               } else
-                                       set_ac3(s, 0);
-                               if (s->status & DO_DUAL_DAC) {
-                                       s->dma_adc.ready = 0;
-                                       if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-                                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                                       else
-                                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                               }
-                               if (val == AFMT_S16_BE)
-                                       s->status |= DO_BIGENDIAN_W;
-                               else
-                                       s->status &= ~DO_BIGENDIAN_W;
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               if (s->status & DO_AC3) return put_user(AFMT_AC3, p);
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
-                                          : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p);
-
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (s->status & DO_DUAL_DAC) {
-                       if (file->f_mode & FMODE_WRITE &&
-                        (s->enable & ENDAC) &&
-                        (s->enable & ENADC))
-                               val |= PCM_ENABLE_OUTPUT;
-                       return put_user(val, p);
-               }
-               if (file->f_mode & FMODE_READ && s->enable & ENADC)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->enable & ENDAC)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               if (s->status & DO_DUAL_DAC) {
-                                       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                                               return ret;
-                               }
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!(s->enable & ENDAC) && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!(s->enable & ENADC) && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               if (s->status & DO_DUAL_DAC) {
-                       if (s->dma_adc.mapped)
-                               s->dma_adc.count &= s->dma_adc.fragsize-1;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       if (s->status & DO_DUAL_DAC) {
-                               if ((val = prog_dmabuf(s, 1)))
-                                       return val;
-                               return put_user(2 * s->dma_dac.fragsize, p);
-                       }
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-                       if (s->status & DO_DUAL_DAC) {
-                               s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;
-                               s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;
-                       }
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.subdivision = val;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.subdivision = val;
-               }
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_READ_FILTER:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-       case SNDCTL_DSP_GETCHANNELMASK:
-               return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, p);
-
-       case SNDCTL_DSP_BIND_CHANNEL:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val == DSP_BIND_QUERY) {
-                       val = DSP_BIND_FRONT;
-                       if (s->status & DO_SPDIF_OUT)
-                               val |= DSP_BIND_SPDIF;
-                       else {
-                               if (s->curr_channels == 4)
-                                       val |= DSP_BIND_SURR;
-                               if (s->curr_channels > 4)
-                                       val |= DSP_BIND_CENTER_LFE;
-                       }
-               } else {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val & DSP_BIND_SPDIF) {
-                                       set_spdifin(s, s->rateadc);
-                                       if (!(s->status & DO_SPDIF_OUT))
-                                               val &= ~DSP_BIND_SPDIF;
-                               }
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val & DSP_BIND_SPDIF) {
-                                       set_spdifout(s, s->ratedac);
-                                       set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1);
-                                       if (!(s->status & DO_SPDIF_OUT))
-                                               val &= ~DSP_BIND_SPDIF;
-                               } else {
-                                       int channels;
-                                       int mask;
-
-                                       mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);
-                                       switch (mask) {
-                                           case DSP_BIND_FRONT:
-                                               channels = 2;
-                                               break;
-                                           case DSP_BIND_FRONT|DSP_BIND_SURR:
-                                               channels = 4;
-                                               break;
-                                           case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
-                                               channels = 6;
-                                               break;
-                                           default:
-                                               channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-                                               break;
-                                       }
-                                       set_dac_channels(s, channels);
-                               }
-                       }
-               }
-               return put_user(val, p);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-        case SNDCTL_DSP_SETSYNCRO:
-                return -EINVAL;
-       case SNDCTL_SPDIF_COPYRIGHT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_copyright(s, val);
-                return 0;
-       case SNDCTL_SPDIF_LOOP:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_loop(s, val);
-                return 0;
-       case SNDCTL_SPDIF_MONITOR:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_monitor(s, val);
-                return 0;
-       case SNDCTL_SPDIF_LEVEL:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifout_level(s, val);
-                return 0;
-       case SNDCTL_SPDIF_INV:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_inverse(s, val);
-                return 0;
-       case SNDCTL_SPDIF_SEL2:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_channel2(s, val);
-                return 0;
-       case SNDCTL_SPDIF_VALID:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_valid(s, val);
-                return 0;
-       case SNDCTL_SPDIFOUT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifout(s, val ? s->ratedac : 0);
-                return 0;
-       case SNDCTL_SPDIFIN:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin(s, val ? s->rateadc : 0);
-                return 0;
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int cm_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned char fmtm = ~0, fmts = 0;
-       struct list_head *list;
-       struct cm_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct cm_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->status &= ~DO_BIGENDIAN_R;
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               set_adc_rate(s, 8000);
-               // spdif-in is turnned off by default
-               set_spdifin(s, 0);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->status &= ~DO_BIGENDIAN_W;
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               s->dma_dac.enabled = 1;
-               set_dac_rate(s, 8000);
-               // clear previous multichannel, spdif, ac3 state
-               set_spdifout(s, 0);
-               set_ac3(s, 0);
-               set_dac_channels(s, 1);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int cm_release(struct inode *inode, struct file *file)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-
-               dealloc_dmabuf(s, &s->dma_dac);
-               if (s->status & DO_DUAL_DAC)
-                       dealloc_dmabuf(s, &s->dma_adc);
-
-               if (s->status & DO_MULTI_CH)
-                       set_dac_channels(s, 1);
-               if (s->status & DO_AC3)
-                       set_ac3(s, 0);
-               if (s->status & DO_SPDIF_OUT)
-                       set_spdifout(s, 0);
-               /* enable SPDIF loop */
-               set_spdif_loop(s, spdif_loop);
-               s->status &= ~DO_BIGENDIAN_W;
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-               s->status &= ~DO_BIGENDIAN_R;
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations cm_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cm_read,
-       .write   = cm_write,
-       .poll    = cm_poll,
-       .ioctl   = cm_ioctl,
-       .mmap    = cm_mmap,
-       .open    = cm_open,
-       .release = cm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_CD, 0x4f4f },
-       { SOUND_MIXER_WRITE_LINE, 0x4f4f },
-       { SOUND_MIXER_WRITE_MIC, 0x4f4f },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4f4f },
-       { SOUND_MIXER_WRITE_VOLUME, 0x4f4f },
-       { SOUND_MIXER_WRITE_PCM, 0x4f4f }
-};
-
-/* check chip version and capability */
-static int query_chip(struct cm_state *s)
-{
-       int ChipVersion = -1;
-       unsigned char RegValue;
-
-       // check reg 0Ch, bit 24-31
-       RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3);
-       if (RegValue == 0) {
-           // check reg 08h, bit 24-28
-           RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3);
-           RegValue &= 0x1f;
-           if (RegValue == 0) {
-               ChipVersion = 33;
-               s->max_channels = 4;
-               s->capability |= CAN_AC3_SW;
-               s->capability |= CAN_DUAL_DAC;
-           } else {
-               ChipVersion = 37;
-               s->max_channels = 4;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-           }
-       } else {
-           // check reg 0Ch, bit 26
-           if (RegValue & (1 << (26-24))) {
-               ChipVersion = 39;
-               if (RegValue & (1 << (24-24)))
-                   s->max_channels = 6;
-               else
-                   s->max_channels = 4;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_MULTI_CH_HW;
-               s->capability |= CAN_LINE_AS_BASS;
-               s->capability |= CAN_MIC_AS_BASS;
-           } else {
-               ChipVersion = 55; // 4 or 6 channels
-               s->max_channels = 6;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_MULTI_CH_HW;
-               s->capability |= CAN_LINE_AS_BASS;
-               s->capability |= CAN_MIC_AS_BASS;
-           }
-       }
-       s->capability |= CAN_LINE_AS_REAR;
-       return ChipVersion;
-}
-
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-static int __devinit cm_create_gameport(struct cm_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, CM_EXTENT_GAME, "cmpci GAME")) {
-               printk(KERN_ERR "cmpci: gameport io ports 0x%#x in use\n", io_port);
-               return -EBUSY;
-       }
-
-       if (!(s->gameport = gp = gameport_allocate_port())) {
-               printk(KERN_ERR "cmpci: can not allocate memory for gameport\n");
-               release_region(io_port, CM_EXTENT_GAME);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "C-Media GP");
-       gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       /* enable joystick */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02);
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static void __devexit cm_free_gameport(struct cm_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-
-               gameport_unregister_port(s->gameport);
-               s->gameport = NULL;
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-               release_region(gpio, CM_EXTENT_GAME);
-       }
-}
-#else
-static inline int cm_create_gameport(struct cm_state *s, int io_port) { return -ENOSYS; }
-static inline void cm_free_gameport(struct cm_state *s) { }
-#endif
-
-#define        echo_option(x)\
-if (x) strcat(options, "" #x " ")
-
-static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct cm_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-       unsigned char reg_mask;
-       int timeout;
-       struct resource *ports;
-       struct {
-               unsigned short  deviceid;
-               char            *devicename;
-       } devicetable[] = {
-               { PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
-               { PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
-               { PCI_DEVICE_ID_CMEDIA_CM8738,  "CM8738" },
-               { PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
-       };
-       char    *devicename = "unknown";
-       char    options[256];
-
-       if ((ret = pci_enable_device(pcidev)))
-               return ret;
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-       if (i) {
-               printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n");
-               return i;
-       }
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
-       if (!s) {
-               printk(KERN_WARNING "cmpci: out of memory\n");
-               return -ENOMEM;
-       }
-       /* search device name */
-       for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) {
-               if (devicetable[i].deviceid == pcidev->device) {
-                       devicename = devicetable[i].devicename;
-                       break;
-               }
-       }
-       memset(s, 0, sizeof(struct cm_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = CM_MAGIC;
-       s->dev = pcidev;
-       s->iobase = pci_resource_start(pcidev, 0);
-       s->iosynth = fmio;
-       s->iomidi = mpuio;
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       s->midi_devc = 0;
-#endif
-       s->status = 0;
-       if (s->iobase == 0)
-               return -ENODEV;
-       s->irq = pcidev->irq;
-
-       if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-               printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
-               ret = -EBUSY;
-               goto err_region5;
-       }
-       /* dump parameters */
-       strcpy(options, "cmpci: ");
-       echo_option(joystick);
-       echo_option(spdif_inverse);
-       echo_option(spdif_loop);
-       echo_option(spdif_out);
-       echo_option(use_line_as_rear);
-       echo_option(use_line_as_bass);
-       echo_option(use_mic_as_bass);
-       echo_option(mic_boost);
-       echo_option(hw_copy);
-       printk(KERN_INFO "%s\n", options);
-
-       /* initialize codec registers */
-       outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-       outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-       /* reset mixer */
-       wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-       /* request irq */
-       if ((ret = request_irq(s->irq, cm_interrupt, IRQF_SHARED, "cmpci", s))) {
-               printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       printk(KERN_INFO "cmpci: found %s adapter at io %#x irq %u\n",
-              devicename, s->iobase, s->irq);
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       pci_set_master(pcidev); /* enable bus mastering */
-       /* initialize the chips */
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       /* set mixer output */
-       frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
-       /* set mixer input */
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-       /* use channel 1 for playback, channel 0 for record */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, CHADC0);
-       /* turn off VMIC3 - mic boost */
-       if (mic_boost)
-               maskb(s->iobase + CODEC_CMI_MIXER2, ~1, 0);
-       else
-               maskb(s->iobase + CODEC_CMI_MIXER2, ~0, 1);
-       s->deviceid = pcidev->device;
-
-       if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738
-        || pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738B) {
-
-               /* chip version and hw capability check */
-               s->chip_version = query_chip(s);
-               printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
-
-               /* set SPDIF-in inverse before enable SPDIF loop */
-               set_spdifin_inverse(s, spdif_inverse);
-
-               /* use SPDIF in #1 */
-               set_spdifin_channel2(s, 0);
-       } else {
-               s->chip_version = 0;
-               /* 8338 will fall here */
-               s->max_channels = 4;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_LINE_AS_REAR;
-       }
-       /* enable SPDIF loop */
-       set_spdif_loop(s, spdif_loop);
-
-       // enable 4 speaker mode (analog duplicate)
-       set_hw_copy(s, hw_copy);
-
-       reg_mask = 0;
-#ifdef CONFIG_SOUND_CMPCI_FM
-       /* disable FM */
-       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-       if (s->iosynth) {
-           /* don't enable OPL3 if there is one */
-           if (opl3_detect(s->iosynth, NULL)) {
-               s->iosynth = 0;
-           } else {
-               /* set IO based at 0x388 */
-               switch (s->iosynth) {
-                   case 0x388:
-                       reg_mask = 0;
-                       break;
-                   case 0x3C8:
-                       reg_mask = 0x01;
-                       break;
-                   case 0x3E0:
-                       reg_mask = 0x02;
-                       break;
-                   case 0x3E8:
-                       reg_mask = 0x03;
-                       break;
-                   default:
-                       s->iosynth = 0;
-                       break;
-               }
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask);
-               /* enable FM */
-               if (s->iosynth) {
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8);
-                       if (opl3_detect(s->iosynth, NULL))
-                               ret = opl3_init(s->iosynth, NULL, THIS_MODULE);
-                       else {
-                               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-                               s->iosynth = 0;
-                       }
-               }
-           }
-       }
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       switch (s->iomidi) {
-           case 0x330:
-               reg_mask = 0;
-               break;
-           case 0x320:
-               reg_mask = 0x20;
-               break;
-           case 0x310:
-               reg_mask = 0x40;
-               break;
-           case 0x300:
-               reg_mask = 0x60;
-               break;
-           default:
-               s->iomidi = 0;
-               goto skip_mpu;
-       }
-       ports = request_region(s->iomidi, 2, "mpu401");
-       if (!ports)
-               goto skip_mpu;
-       /* disable MPU-401 */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-       s->mpu_data.name = "cmpci mpu";
-       s->mpu_data.io_base = s->iomidi;
-       s->mpu_data.irq = -s->irq;      // tell mpu401 to share irq
-       if (probe_mpu401(&s->mpu_data, ports)) {
-               release_region(s->iomidi, 2);
-               s->iomidi = 0;
-               goto skip_mpu;
-       }
-       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x60, reg_mask);
-       /* enable MPU-401 */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-       /* clear all previously received interrupt */
-       for (timeout = 900000; timeout > 0; timeout--) {
-               if ((inb(s->iomidi + 1) && 0x80) == 0)
-                       inb(s->iomidi);
-               else
-                       break;
-       }
-       if (!probe_mpu401(&s->mpu_data, ports)) {
-               release_region(s->iomidi, 2);
-               s->iomidi = 0;
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-       } else {
-               attach_mpu401(&s->mpu_data, THIS_MODULE);
-               s->midi_devc = s->mpu_data.slots[1];
-       }
-skip_mpu:
-#endif
-       /* disable joystick port */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-       if (joystick)
-               cm_create_gameport(s, 0x200);
-
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
-err_dev2:
-       unregister_sound_dsp(s->dev_audio);
-err_dev1:
-       printk(KERN_ERR "cmpci: cannot register misc device\n");
-       free_irq(s->irq, s);
-err_irq:
-       release_region(s->iobase, CM_EXTENT_CODEC);
-err_region5:
-       kfree(s);
-       return ret;
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
-MODULE_DESCRIPTION("CM8x38 Audio Driver");
-MODULE_LICENSE("GPL");
-
-static void __devexit cm_remove(struct pci_dev *dev)
-{
-       struct cm_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-
-       cm_free_gameport(s);
-
-#ifdef CONFIG_SOUND_CMPCI_FM
-       if (s->iosynth) {
-               /* disable FM */
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-       }
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       if (s->iomidi) {
-               unload_mpu401(&s->mpu_data);
-               /* disable MPU-401 */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-       }
-#endif
-       set_spdif_loop(s, 0);
-       list_del(&s->devs);
-       outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-       synchronize_irq(s->irq);
-       outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-       free_irq(s->irq, s);
-
-       /* reset mixer */
-       wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-       release_region(s->iobase, CM_EXTENT_CODEC);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] __devinitdata = {
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver cm_driver = {
-       .name    = "cmpci",
-       .id_table = id_table,
-       .probe   = cm_probe,
-       .remove  = __devexit_p(cm_remove)
-};
-
-static int __init init_cmpci(void)
-{
-       printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&cm_driver);
-}
-
-static void __exit cleanup_cmpci(void)
-{
-       printk(KERN_INFO "cmpci: unloading\n");
-       pci_unregister_driver(&cm_driver);
-}
-
-module_init(init_cmpci);
-module_exit(cleanup_cmpci);
diff --git a/sound/oss/cs4281/Makefile b/sound/oss/cs4281/Makefile
deleted file mode 100644 (file)
index 6d527e8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for Cirrus Logic-Crystal CS4281 
-#
-
-obj-$(CONFIG_SOUND_CS4281) += cs4281.o
-
-cs4281-objs += cs4281m.o
diff --git a/sound/oss/cs4281/cs4281_hwdefs.h b/sound/oss/cs4281/cs4281_hwdefs.h
deleted file mode 100644 (file)
index 701d595..0000000
+++ /dev/null
@@ -1,1234 +0,0 @@
-//****************************************************************************
-//
-// HWDEFS.H - Definitions of the registers and data structures used by the
-//            CS4281
-//
-// Copyright (c) 1999,2000,2001 Crystal Semiconductor Corp.
-//
-//****************************************************************************
-
-#ifndef _H_HWDEFS
-#define _H_HWDEFS
-
-//****************************************************************************
-//
-// The following define the offsets of the registers located in the PCI
-// configuration space of the CS4281 part.
-//
-//****************************************************************************
-#define PCICONFIG_DEVID_VENID                   0x00000000L
-#define PCICONFIG_STATUS_COMMAND                0x00000004L
-#define PCICONFIG_CLASS_REVISION                0x00000008L
-#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
-#define PCICONFIG_BA0                           0x00000010L
-#define PCICONFIG_BA1                           0x00000014L
-#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
-#define PCICONFIG_INTERRUPT                     0x0000003CL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers accessed via base address
-// register zero on the CS4281 part.
-//
-//****************************************************************************
-#define BA0_HISR                                0x00000000L
-#define BA0_HICR                                0x00000008L
-#define BA0_HIMR                                0x0000000CL
-#define BA0_IIER                                0x00000010L
-#define BA0_HDSR0                               0x000000F0L
-#define BA0_HDSR1                               0x000000F4L
-#define BA0_HDSR2                               0x000000F8L
-#define BA0_HDSR3                               0x000000FCL
-#define BA0_DCA0                                0x00000110L
-#define BA0_DCC0                                0x00000114L
-#define BA0_DBA0                                0x00000118L
-#define BA0_DBC0                                0x0000011CL
-#define BA0_DCA1                                0x00000120L
-#define BA0_DCC1                                0x00000124L
-#define BA0_DBA1                                0x00000128L
-#define BA0_DBC1                                0x0000012CL
-#define BA0_DCA2                                0x00000130L
-#define BA0_DCC2                                0x00000134L
-#define BA0_DBA2                                0x00000138L
-#define BA0_DBC2                                0x0000013CL
-#define BA0_DCA3                                0x00000140L
-#define BA0_DCC3                                0x00000144L
-#define BA0_DBA3                                0x00000148L
-#define BA0_DBC3                                0x0000014CL
-#define BA0_DMR0                                0x00000150L
-#define BA0_DCR0                                0x00000154L
-#define BA0_DMR1                                0x00000158L
-#define BA0_DCR1                                0x0000015CL
-#define BA0_DMR2                                0x00000160L
-#define BA0_DCR2                                0x00000164L
-#define BA0_DMR3                                0x00000168L
-#define BA0_DCR3                                0x0000016CL
-#define BA0_DLMR                                0x00000170L
-#define BA0_DLSR                                0x00000174L
-#define BA0_FCR0                                0x00000180L
-#define BA0_FCR1                                0x00000184L
-#define BA0_FCR2                                0x00000188L
-#define BA0_FCR3                                0x0000018CL
-#define BA0_FPDR0                               0x00000190L
-#define BA0_FPDR1                               0x00000194L
-#define BA0_FPDR2                               0x00000198L
-#define BA0_FPDR3                               0x0000019CL
-#define BA0_FCHS                                0x0000020CL
-#define BA0_FSIC0                               0x00000210L
-#define BA0_FSIC1                               0x00000214L
-#define BA0_FSIC2                               0x00000218L
-#define BA0_FSIC3                               0x0000021CL
-#define BA0_PCICFG00                            0x00000300L
-#define BA0_PCICFG04                            0x00000304L
-#define BA0_PCICFG08                            0x00000308L
-#define BA0_PCICFG0C                            0x0000030CL
-#define BA0_PCICFG10                            0x00000310L
-#define BA0_PCICFG14                            0x00000314L
-#define BA0_PCICFG18                            0x00000318L
-#define BA0_PCICFG1C                            0x0000031CL
-#define BA0_PCICFG20                            0x00000320L
-#define BA0_PCICFG24                            0x00000324L
-#define BA0_PCICFG28                            0x00000328L
-#define BA0_PCICFG2C                            0x0000032CL
-#define BA0_PCICFG30                            0x00000330L
-#define BA0_PCICFG34                            0x00000334L
-#define BA0_PCICFG38                            0x00000338L
-#define BA0_PCICFG3C                            0x0000033CL
-#define BA0_PCICFG40                            0x00000340L
-#define BA0_PMCS                                0x00000344L
-#define BA0_CWPR                                0x000003E0L
-#define BA0_EPPMC                               0x000003E4L
-#define BA0_GPIOR                               0x000003E8L
-#define BA0_SPMC                                0x000003ECL
-#define BA0_CFLR                                0x000003F0L
-#define BA0_IISR                                0x000003F4L
-#define BA0_TMS                                 0x000003F8L
-#define BA0_SSVID                               0x000003FCL
-#define BA0_CLKCR1                              0x00000400L
-#define BA0_FRR                                 0x00000410L
-#define BA0_SLT12O                              0x0000041CL
-#define BA0_SERMC                               0x00000420L
-#define BA0_SERC1                               0x00000428L
-#define BA0_SERC2                               0x0000042CL
-#define BA0_SLT12M                              0x0000045CL
-#define BA0_ACCTL                               0x00000460L
-#define BA0_ACSTS                               0x00000464L
-#define BA0_ACOSV                               0x00000468L
-#define BA0_ACCAD                               0x0000046CL
-#define BA0_ACCDA                               0x00000470L
-#define BA0_ACISV                               0x00000474L
-#define BA0_ACSAD                               0x00000478L
-#define BA0_ACSDA                               0x0000047CL
-#define BA0_JSPT                                0x00000480L
-#define BA0_JSCTL                               0x00000484L
-#define BA0_MIDCR                               0x00000490L
-#define BA0_MIDCMD                              0x00000494L
-#define BA0_MIDSR                               0x00000494L
-#define BA0_MIDWP                               0x00000498L
-#define BA0_MIDRP                               0x0000049CL
-#define BA0_AODSD1                              0x000004A8L
-#define BA0_AODSD2                              0x000004ACL
-#define BA0_CFGI                                0x000004B0L
-#define BA0_SLT12M2                             0x000004DCL
-#define BA0_ACSTS2                              0x000004E4L
-#define BA0_ACISV2                              0x000004F4L
-#define BA0_ACSAD2                              0x000004F8L
-#define BA0_ACSDA2                              0x000004FCL
-#define BA0_IOTGP                               0x00000500L
-#define BA0_IOTSB                               0x00000504L
-#define BA0_IOTFM                               0x00000508L
-#define BA0_IOTDMA                              0x0000050CL
-#define BA0_IOTAC0                              0x00000500L
-#define BA0_IOTAC1                              0x00000504L
-#define BA0_IOTAC2                              0x00000508L
-#define BA0_IOTAC3                              0x0000050CL
-#define BA0_IOTPCP                              0x0000052CL
-#define BA0_IOTCC                               0x00000530L
-#define BA0_IOTCR                               0x0000058CL
-#define BA0_PCPRR                               0x00000600L
-#define BA0_PCPGR                               0x00000604L
-#define BA0_PCPCR                               0x00000608L
-#define BA0_PCPCIEN                             0x00000608L
-#define BA0_SBMAR                               0x00000700L
-#define BA0_SBMDR                               0x00000704L
-#define BA0_SBRR                                0x00000708L
-#define BA0_SBRDP                               0x0000070CL
-#define BA0_SBWDP                               0x00000710L
-#define BA0_SBWBS                               0x00000710L
-#define BA0_SBRBS                               0x00000714L
-#define BA0_FMSR                                0x00000730L
-#define BA0_B0AP                                0x00000730L
-#define BA0_FMDP                                0x00000734L
-#define BA0_B1AP                                0x00000738L
-#define BA0_B1DP                                0x0000073CL
-#define BA0_SSPM                                0x00000740L
-#define BA0_DACSR                               0x00000744L
-#define BA0_ADCSR                               0x00000748L
-#define BA0_SSCR                                0x0000074CL
-#define BA0_FMLVC                               0x00000754L
-#define BA0_FMRVC                               0x00000758L
-#define BA0_SRCSA                               0x0000075CL
-#define BA0_PPLVC                               0x00000760L
-#define BA0_PPRVC                               0x00000764L
-#define BA0_PASR                                0x00000768L
-#define BA0_CASR                                0x0000076CL
-
-//****************************************************************************
-//
-// The following define the offsets of the AC97 shadow registers, which appear
-// as a virtual extension to the base address register zero memory range.
-//
-//****************************************************************************
-#define AC97_REG_OFFSET_MASK                    0x0000007EL
-#define AC97_CODEC_NUMBER_MASK                  0x00003000L
-
-#define BA0_AC97_RESET                          0x00001000L
-#define BA0_AC97_MASTER_VOLUME                  0x00001002L
-#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
-#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
-#define BA0_AC97_MASTER_TONE                    0x00001008L
-#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
-#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
-#define BA0_AC97_MIC_VOLUME                     0x0000100EL
-#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
-#define BA0_AC97_CD_VOLUME                      0x00001012L
-#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
-#define BA0_AC97_AUX_VOLUME                     0x00001016L
-#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
-#define BA0_AC97_RECORD_SELECT                  0x0000101AL
-#define BA0_AC97_RECORD_GAIN                    0x0000101CL
-#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
-#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
-#define BA0_AC97_3D_CONTROL                     0x00001022L
-#define BA0_AC97_MODEM_RATE                     0x00001024L
-#define BA0_AC97_POWERDOWN                      0x00001026L
-#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
-#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
-#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
-#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
-#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
-#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
-#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
-#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
-#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
-#define BA0_AC97_RESERVED_3A                    0x0000103AL
-#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
-#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
-#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
-#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
-#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
-#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
-#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
-#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
-#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
-#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
-#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
-#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
-#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
-#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
-#define BA0_AC97_RESERVED_58                    0x00001058L
-#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
-#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
-#define BA0_AC97_AC_MODE                        0x0000105EL
-#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
-#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
-#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
-#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
-#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
-#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
-#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
-#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
-#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
-#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
-#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
-#define BA0_AC97_CAL_ADDRESS                    0x00001076L
-#define BA0_AC97_CAL_DATA                       0x00001078L
-#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
-#define BA0_AC97_VENDOR_ID1                     0x0000107CL
-#define BA0_AC97_VENDOR_ID2                     0x0000107EL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers and memories accessed via
-// base address register one on the CS4281 part.
-//
-//****************************************************************************
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI device ID/vendor ID
-// register.
-//
-//****************************************************************************
-#define PDV_VENID_MASK                          0x0000FFFFL
-#define PDV_DEVID_MASK                          0xFFFF0000L
-#define PDV_VENID_SHIFT                         0L
-#define PDV_DEVID_SHIFT                         16L
-#define VENID_CIRRUS_LOGIC                      0x1013L
-#define DEVID_CS4281                            0x6005L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI status and command
-// register.
-//
-//****************************************************************************
-#define PSC_IO_SPACE_ENABLE                     0x00000001L
-#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
-#define PSC_BUS_MASTER_ENABLE                   0x00000004L
-#define PSC_SPECIAL_CYCLES                      0x00000008L
-#define PSC_MWI_ENABLE                          0x00000010L
-#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
-#define PSC_PARITY_RESPONSE                     0x00000040L
-#define PSC_WAIT_CONTROL                        0x00000080L
-#define PSC_SERR_ENABLE                         0x00000100L
-#define PSC_FAST_B2B_ENABLE                     0x00000200L
-#define PSC_UDF_MASK                            0x007F0000L
-#define PSC_FAST_B2B_CAPABLE                    0x00800000L
-#define PSC_PARITY_ERROR_DETECTED               0x01000000L
-#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
-#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
-#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
-#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
-#define PSC_SIGNALLED_SERR                      0x40000000L
-#define PSC_DETECTED_PARITY_ERROR               0x80000000L
-#define PSC_UDF_SHIFT                           16L
-#define PSC_DEVSEL_TIMING_SHIFT                 25L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI class/revision ID
-// register.
-//
-//****************************************************************************
-#define PCR_REVID_MASK                          0x000000FFL
-#define PCR_INTERFACE_MASK                      0x0000FF00L
-#define PCR_SUBCLASS_MASK                       0x00FF0000L
-#define PCR_CLASS_MASK                          0xFF000000L
-#define PCR_REVID_SHIFT                         0L
-#define PCR_INTERFACE_SHIFT                     8L
-#define PCR_SUBCLASS_SHIFT                      16L
-#define PCR_CLASS_SHIFT                         24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI latency timer register.
-//
-//****************************************************************************
-#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
-#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
-#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
-#define PLT_BIST_MASK                           0xFF000000L
-#define PLT_CACHE_LINE_SIZE_SHIFT               0L
-#define PLT_LATENCY_TIMER_SHIFT                 8L
-#define PLT_HEADER_TYPE_SHIFT                   16L
-#define PLT_BIST_SHIFT                          24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI base address registers.
-//
-//****************************************************************************
-#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
-#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
-#define PBAR_NOT_PREFETCHABLE                   0x00000008L
-#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
-#define PBAR_LOCATION_TYPE_SHIFT                1L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI subsystem ID/subsystem
-// vendor ID register.
-//
-//****************************************************************************
-#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
-#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
-#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
-#define PSS_SUBSYSTEM_ID_SHIFT                  16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI interrupt register.
-//
-//****************************************************************************
-#define PI_LINE_MASK                            0x000000FFL
-#define PI_PIN_MASK                             0x0000FF00L
-#define PI_MIN_GRANT_MASK                       0x00FF0000L
-#define PI_MAX_LATENCY_MASK                     0xFF000000L
-#define PI_LINE_SHIFT                           0L
-#define PI_PIN_SHIFT                            8L
-#define PI_MIN_GRANT_SHIFT                      16L
-#define PI_MAX_LATENCY_SHIFT                    24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt status
-// register.
-//
-//****************************************************************************
-#define HISR_HVOLMASK                            0x00000003L
-#define HISR_VDNI                                0x00000001L
-#define HISR_VUPI                                0x00000002L
-#define HISR_GP1I                                0x00000004L
-#define HISR_GP3I                                0x00000008L
-#define HISR_GPSI                                0x00000010L
-#define HISR_GPPI                                0x00000020L
-#define HISR_DMAI                                0x00040000L
-#define HISR_FIFOI                               0x00100000L
-#define HISR_HVOL                                0x00200000L
-#define HISR_MIDI                                0x00400000L
-#define HISR_SBINT                               0x00800000L
-#define HISR_INTENA                              0x80000000L
-#define HISR_DMA_MASK                            0x00000F00L
-#define HISR_FIFO_MASK                           0x0000F000L
-#define HISR_DMA_SHIFT                           8L
-#define HISR_FIFO_SHIFT                          12L
-#define HISR_FIFO0                               0x00001000L
-#define HISR_FIFO1                               0x00002000L
-#define HISR_FIFO2                               0x00004000L
-#define HISR_FIFO3                               0x00008000L
-#define HISR_DMA0                                0x00000100L
-#define HISR_DMA1                                0x00000200L
-#define HISR_DMA2                                0x00000400L
-#define HISR_DMA3                                0x00000800L
-#define HISR_RESERVED                            0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt control
-// register.
-//
-//****************************************************************************
-#define HICR_IEV                                 0x00000001L
-#define HICR_CHGM                                0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Mode Register n
-// (DMRn)
-//
-//****************************************************************************
-#define DMRn_TR_MASK                             0x0000000CL
-#define DMRn_TR_SHIFT                            2L
-#define DMRn_AUTO                                0x00000010L
-#define DMRn_TR_READ                             0x00000008L
-#define DMRn_TR_WRITE                            0x00000004L
-#define DMRn_TYPE_MASK                           0x000000C0L
-#define DMRn_TYPE_SHIFT                          6L
-#define DMRn_SIZE8                               0x00010000L
-#define DMRn_MONO                                0x00020000L
-#define DMRn_BEND                                0x00040000L
-#define DMRn_USIGN                               0x00080000L
-#define DMRn_SIZE20                              0x00100000L
-#define DMRn_SWAPC                               0x00400000L
-#define DMRn_CBC                                 0x01000000L
-#define DMRn_TBC                                 0x02000000L
-#define DMRn_POLL                                0x10000000L
-#define DMRn_DMA                                 0x20000000L
-#define DMRn_FSEL_MASK                           0xC0000000L
-#define DMRn_FSEL_SHIFT                          30L
-#define DMRn_FSEL0                               0x00000000L
-#define DMRn_FSEL1                               0x40000000L
-#define DMRn_FSEL2                               0x80000000L
-#define DMRn_FSEL3                               0xC0000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Command Register n
-// (DCRn)
-//
-//****************************************************************************
-#define DCRn_HTCIE                               0x00020000L
-#define DCRn_TCIE                                0x00010000L
-#define DCRn_MSK                                 0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the FIFO Control 
-// register n.(FCRn)
-//
-//****************************************************************************
-#define FCRn_OF_MASK                            0x0000007FL
-#define FCRn_OF_SHIFT                           0L
-#define FCRn_SZ_MASK                            0x00007F00L
-#define FCRn_SZ_SHIFT                           8L
-#define FCRn_LS_MASK                            0x001F0000L
-#define FCRn_LS_SHIFT                           16L
-#define FCRn_RS_MASK                            0x1F000000L
-#define FCRn_RS_SHIFT                           24L
-#define FCRn_FEN                                0x80000000L
-#define FCRn_PSH                                0x20000000L
-#define FCRn_DACZ                               0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port Power Management
-// control register.(SPMC)
-//
-//****************************************************************************
-#define SPMC_RSTN                               0x00000001L
-#define SPMC_ASYN                               0x00000002L
-#define SPMC_WUP1                               0x00000004L
-#define SPMC_WUP2                               0x00000008L
-#define SPMC_ASDI2E                             0x00000100L
-#define SPMC_ESSPD                              0x00000200L
-#define SPMC_GISPEN                             0x00004000L
-#define SPMC_GIPPEN                             0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Configuration Load register.
-// (CFLR)
-//
-//****************************************************************************
-#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
-#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
-
-#define CFLR_CB0_MASK                            0x000000FFL
-#define CFLR_CB1_MASK                            0x0000FF00L
-#define CFLR_CB2_MASK                            0x00FF0000L
-#define CFLR_CB3_MASK                            0xFF000000L
-#define CFLR_CB0_SHIFT                           0L
-#define CFLR_CB1_SHIFT                           8L
-#define CFLR_CB2_SHIFT                           16L
-#define CFLR_CB3_SHIFT                           24L
-
-#define IOTCR_DMA0                              0x00000000L
-#define IOTCR_DMA1                              0x00000400L
-#define IOTCR_DMA2                              0x00000800L
-#define IOTCR_DMA3                              0x00000C00L
-#define IOTCR_CCLS                              0x00000100L
-#define IOTCR_PCPCI                             0x00000200L
-#define IOTCR_DDMA                              0x00000300L
-
-#define SBWBS_WBB                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the SRC Slot Assignment Register
-// (SRCSA)
-//
-//****************************************************************************
-#define SRCSA_PLSS_MASK                         0x0000001FL
-#define SRCSA_PLSS_SHIFT                        0L
-#define SRCSA_PRSS_MASK                         0x00001F00L
-#define SRCSA_PRSS_SHIFT                        8L
-#define SRCSA_CLSS_MASK                         0x001F0000L
-#define SRCSA_CLSS_SHIFT                        16L
-#define SRCSA_CRSS_MASK                         0x1F000000L
-#define SRCSA_CRSS_SHIFT                        24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Power Management
-// register.(SSPM)
-//
-//****************************************************************************
-#define SSPM_FPDN                               0x00000080L
-#define SSPM_MIXEN                              0x00000040L
-#define SSPM_CSRCEN                             0x00000020L
-#define SSPM_PSRCEN                             0x00000010L
-#define SSPM_JSEN                               0x00000008L
-#define SSPM_ACLEN                              0x00000004L
-#define SSPM_FMEN                               0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Control
-// Register. (SSCR)
-//
-//****************************************************************************
-#define SSCR_SB                                 0x00000004L
-#define SSCR_HVC                                0x00000008L
-#define SSCR_LPFIFO                             0x00000040L
-#define SSCR_LPSRC                              0x00000080L
-#define SSCR_XLPSRC                             0x00000100L
-#define SSCR_MVMD                               0x00010000L
-#define SSCR_MVAD                               0x00020000L
-#define SSCR_MVLD                               0x00040000L
-#define SSCR_MVCS                               0x00080000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Clock Control Register 1. 
-// (CLKCR1)
-//
-//****************************************************************************
-#define CLKCR1_DLLSS_MASK                       0x0000000CL
-#define CLKCR1_DLLSS_SHIFT                      2L
-#define CLKCR1_DLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_DLLOS                            0x00000040L
-#define CLKCR1_CKRA                             0x00010000L
-#define CLKCR1_CKRN                             0x00020000L
-#define CLKCR1_DLLRDY                           0x01000000L
-#define CLKCR1_CLKON                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound Blaster Read Buffer
-// Status.(SBRBS)
-//
-//****************************************************************************
-#define SBRBS_RD_MASK                           0x0000007FL
-#define SBRBS_RD_SHIFT                          0L
-#define SBRBS_RBF                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port master control
-// register.(SERMC)
-//
-//****************************************************************************
-#define SERMC_MSPE                              0x00000001L
-#define SERMC_PTC_MASK                          0x0000000EL
-#define SERMC_PTC_SHIFT                         1L
-#define SERMC_PTC_AC97                          0x00000002L
-#define SERMC_PLB                               0x00000010L
-#define SERMC_PXLB                              0x00000020L
-#define SERMC_LOFV                              0x00080000L
-#define SERMC_SLB                               0x00100000L
-#define SERMC_SXLB                              0x00200000L
-#define SERMC_ODSEN1                            0x01000000L
-#define SERMC_ODSEN2                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the General Purpose I/O Register. 
-// (GPIOR)
-//
-//****************************************************************************
-#define GPIOR_VDNS                              0x00000001L
-#define GPIOR_VUPS                              0x00000002L
-#define GPIOR_GP1S                              0x00000004L
-#define GPIOR_GP3S                              0x00000008L
-#define GPIOR_GPSS                              0x00000010L
-#define GPIOR_GPPS                              0x00000020L
-#define GPIOR_GP1D                              0x00000400L
-#define GPIOR_GP3D                              0x00000800L
-#define GPIOR_VDNLT                             0x00010000L
-#define GPIOR_VDNPO                             0x00020000L
-#define GPIOR_VDNST                             0x00040000L
-#define GPIOR_VDNW                              0x00080000L
-#define GPIOR_VUPLT                             0x00100000L
-#define GPIOR_VUPPO                             0x00200000L
-#define GPIOR_VUPST                             0x00400000L
-#define GPIOR_VUPW                              0x00800000L
-#define GPIOR_GP1OE                             0x01000000L
-#define GPIOR_GP1PT                             0x02000000L
-#define GPIOR_GP1ST                             0x04000000L
-#define GPIOR_GP1W                              0x08000000L
-#define GPIOR_GP3OE                             0x10000000L
-#define GPIOR_GP3PT                             0x20000000L
-#define GPIOR_GP3ST                             0x40000000L
-#define GPIOR_GP3W                              0x80000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the clock control register 1.
-//
-//****************************************************************************
-#define CLKCR1_PLLSS_MASK                       0x0000000CL
-#define CLKCR1_PLLSS_SERIAL                     0x00000000L
-#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
-#define CLKCR1_PLLSS_PCI                        0x00000008L
-#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
-#define CLKCR1_PLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_PLLOS                            0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the feature reporting register.
-//
-//****************************************************************************
-#define FRR_FAB_MASK                            0x00000003L
-#define FRR_MASK_MASK                           0x0000001CL
-#define FRR_ID_MASK                             0x00003000L
-#define FRR_FAB_SHIFT                           0L
-#define FRR_MASK_SHIFT                          2L
-#define FRR_ID_SHIFT                            12L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 1 configuration
-// register.
-//
-//****************************************************************************
-#define SERC1_VALUE                             0x00000003L
-#define SERC1_SO1EN                             0x00000001L
-#define SERC1_SO1F_MASK                         0x0000000EL
-#define SERC1_SO1F_CS423X                       0x00000000L
-#define SERC1_SO1F_AC97                         0x00000002L
-#define SERC1_SO1F_DAC                          0x00000004L
-#define SERC1_SO1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 2 configuration
-// register.
-//
-//****************************************************************************
-#define SERC2_VALUE                             0x00000003L
-#define SERC2_SI1EN                             0x00000001L
-#define SERC2_SI1F_MASK                         0x0000000EL
-#define SERC2_SI1F_CS423X                       0x00000000L
-#define SERC2_SI1F_AC97                         0x00000002L
-#define SERC2_SI1F_ADC                          0x00000004L
-#define SERC2_SI1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 control register.
-//
-//****************************************************************************
-#define ACCTL_ESYN                              0x00000002L
-#define ACCTL_VFRM                              0x00000004L
-#define ACCTL_DCV                               0x00000008L
-#define ACCTL_CRW                               0x00000010L
-#define ACCTL_TC                                0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register.
-//
-//****************************************************************************
-#define ACSTS_CRDY                              0x00000001L
-#define ACSTS_VSTS                              0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 output slot valid
-// register.
-//
-//****************************************************************************
-#define ACOSV_SLV3                              0x00000001L
-#define ACOSV_SLV4                              0x00000002L
-#define ACOSV_SLV5                              0x00000004L
-#define ACOSV_SLV6                              0x00000008L
-#define ACOSV_SLV7                              0x00000010L
-#define ACOSV_SLV8                              0x00000020L
-#define ACOSV_SLV9                              0x00000040L
-#define ACOSV_SLV10                             0x00000080L
-#define ACOSV_SLV11                             0x00000100L
-#define ACOSV_SLV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command address
-// register.
-//
-//****************************************************************************
-#define ACCAD_CI_MASK                           0x0000007FL
-#define ACCAD_CI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command data register.
-//
-//****************************************************************************
-#define ACCDA_CD_MASK                           0x0000FFFFL
-#define ACCDA_CD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register.
-//
-//****************************************************************************
-#define ACISV_ISV3                              0x00000001L
-#define ACISV_ISV4                              0x00000002L
-#define ACISV_ISV5                              0x00000004L
-#define ACISV_ISV6                              0x00000008L
-#define ACISV_ISV7                              0x00000010L
-#define ACISV_ISV8                              0x00000020L
-#define ACISV_ISV9                              0x00000040L
-#define ACISV_ISV10                             0x00000080L
-#define ACISV_ISV11                             0x00000100L
-#define ACISV_ISV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register.
-//
-//****************************************************************************
-#define ACSAD_SI_MASK                           0x0000007FL
-#define ACSAD_SI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register.
-//
-//****************************************************************************
-#define ACSDA_SD_MASK                           0x0000FFFFL
-#define ACSDA_SD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers (all 12).
-//
-//****************************************************************************
-#define IOTAC_SA_MASK                           0x0000FFFFL
-#define IOTAC_MSK_MASK                          0x000F0000L
-#define IOTAC_IODC_MASK                         0x06000000L
-#define IOTAC_IODC_16_BIT                       0x00000000L
-#define IOTAC_IODC_10_BIT                       0x02000000L
-#define IOTAC_IODC_12_BIT                       0x04000000L
-#define IOTAC_WSPI                              0x08000000L
-#define IOTAC_RSPI                              0x10000000L
-#define IOTAC_WSE                               0x20000000L
-#define IOTAC_WE                                0x40000000L
-#define IOTAC_RE                                0x80000000L
-#define IOTAC_SA_SHIFT                          0L
-#define IOTAC_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI master enable
-// register.
-//
-//****************************************************************************
-#define PCPCIEN_EN                              0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick poll/trigger
-// register.
-//
-//****************************************************************************
-#define JSPT_CAX                                0x00000001L
-#define JSPT_CAY                                0x00000002L
-#define JSPT_CBX                                0x00000004L
-#define JSPT_CBY                                0x00000008L
-#define JSPT_BA1                                0x00000010L
-#define JSPT_BA2                                0x00000020L
-#define JSPT_BB1                                0x00000040L
-#define JSPT_BB2                                0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick control register.
-// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
-//
-//****************************************************************************
-#define JSCTL_SP_MASK                           0x00000003L
-#define JSCTL_SP_SLOW                           0x00000000L
-#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
-#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
-#define JSCTL_SP_FAST                           0x00000003L
-#define JSCTL_ARE                               0x00000004L
-#define JSCTL_TBF                               0x00000100L
-
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI control register.
-//
-//****************************************************************************
-#define MIDCR_TXE                               0x00000001L
-#define MIDCR_RXE                               0x00000002L
-#define MIDCR_RIE                               0x00000004L
-#define MIDCR_TIE                               0x00000008L
-#define MIDCR_MLB                               0x00000010L
-#define MIDCR_MRST                              0x00000020L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI status register.
-//
-//****************************************************************************
-#define MIDSR_RBE                               0x00000080L
-#define MIDSR_RDA                               0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI write port register.
-//
-//****************************************************************************
-#define MIDWP_MWD_MASK                          0x000000FFL
-#define MIDWP_MWD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI read port register.
-//
-//****************************************************************************
-#define MIDRP_MRD_MASK                          0x000000FFL
-#define MIDRP_MRD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the configuration interface
-// register.
-//
-//****************************************************************************
-#define CFGI_CLK                                0x00000001L
-#define CFGI_DOUT                               0x00000002L
-#define CFGI_DIN_EEN                            0x00000004L
-#define CFGI_EELD                               0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the subsystem ID and vendor ID
-// register.
-//
-//****************************************************************************
-#define SSVID_VID_MASK                          0x0000FFFFL
-#define SSVID_SID_MASK                          0xFFFF0000L
-#define SSVID_VID_SHIFT                         0L
-#define SSVID_SID_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the GPIO pin interface register.
-//
-//****************************************************************************
-#define GPIOR_VOLDN                             0x00000001L
-#define GPIOR_VOLUP                             0x00000002L
-#define GPIOR_SI2D                              0x00000004L
-#define GPIOR_SI2OE                             0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register 2.
-//
-//****************************************************************************
-#define ACSTS2_CRDY                             0x00000001L
-#define ACSTS2_VSTS                             0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register 2.
-//
-//****************************************************************************
-#define ACISV2_ISV3                             0x00000001L
-#define ACISV2_ISV4                             0x00000002L
-#define ACISV2_ISV5                             0x00000004L
-#define ACISV2_ISV6                             0x00000008L
-#define ACISV2_ISV7                             0x00000010L
-#define ACISV2_ISV8                             0x00000020L
-#define ACISV2_ISV9                             0x00000040L
-#define ACISV2_ISV10                            0x00000080L
-#define ACISV2_ISV11                            0x00000100L
-#define ACISV2_ISV12                            0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register 2.
-//
-//****************************************************************************
-#define ACSAD2_SI_MASK                          0x0000007FL
-#define ACSAD2_SI_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register 2.
-//
-//****************************************************************************
-#define ACSDA2_SD_MASK                          0x0000FFFFL
-#define ACSDA2_SD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap control register.
-//
-//****************************************************************************
-#define IOTCR_ITD                               0x00000001L
-#define IOTCR_HRV                               0x00000002L
-#define IOTCR_SRV                               0x00000004L
-#define IOTCR_DTI                               0x00000008L
-#define IOTCR_DFI                               0x00000010L
-#define IOTCR_DDP                               0x00000020L
-#define IOTCR_JTE                               0x00000040L
-#define IOTCR_PPE                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Hardware Master Volume.  
-//
-//****************************************************************************
-#define IOTGP_SA_MASK                           0x0000FFFFL
-#define IOTGP_MSK_MASK                          0x000F0000L
-#define IOTGP_IODC_MASK                         0x06000000L
-#define IOTGP_IODC_16_BIT                       0x00000000L
-#define IOTGP_IODC_10_BIT                       0x02000000L
-#define IOTGP_IODC_12_BIT                       0x04000000L
-#define IOTGP_WSPI                              0x08000000L
-#define IOTGP_RSPI                              0x10000000L
-#define IOTGP_WSE                               0x20000000L
-#define IOTGP_WE                                0x40000000L
-#define IOTGP_RE                                0x80000000L
-#define IOTGP_SA_SHIFT                          0L
-#define IOTGP_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Sound Blaster
-//
-//****************************************************************************
-#define IOTSB_SA_MASK                           0x0000FFFFL
-#define IOTSB_MSK_MASK                          0x000F0000L
-#define IOTSB_IODC_MASK                         0x06000000L
-#define IOTSB_IODC_16_BIT                       0x00000000L
-#define IOTSB_IODC_10_BIT                       0x02000000L
-#define IOTSB_IODC_12_BIT                       0x04000000L
-#define IOTSB_WSPI                              0x08000000L
-#define IOTSB_RSPI                              0x10000000L
-#define IOTSB_WSE                               0x20000000L
-#define IOTSB_WE                                0x40000000L
-#define IOTSB_RE                                0x80000000L
-#define IOTSB_SA_SHIFT                          0L
-#define IOTSB_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for FM.
-//
-//****************************************************************************
-#define IOTFM_SA_MASK                           0x0000FFFFL
-#define IOTFM_MSK_MASK                          0x000F0000L
-#define IOTFM_IODC_MASK                         0x06000000L
-#define IOTFM_IODC_16_BIT                       0x00000000L
-#define IOTFM_IODC_10_BIT                       0x02000000L
-#define IOTFM_IODC_12_BIT                       0x04000000L
-#define IOTFM_WSPI                              0x08000000L
-#define IOTFM_RSPI                              0x10000000L
-#define IOTFM_WSE                               0x20000000L
-#define IOTFM_WE                                0x40000000L
-#define IOTFM_RE                                0x80000000L
-#define IOTFM_SA_SHIFT                          0L
-#define IOTFM_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI request register.
-//
-//****************************************************************************
-#define PCPRR_RDC_MASK                         0x00000007L
-#define PCPRR_REQ                              0x00008000L
-#define PCPRR_RDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI grant register.
-//
-//****************************************************************************
-#define PCPGR_GDC_MASK                         0x00000007L
-#define PCPGR_VL                               0x00008000L
-#define PCPGR_GDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI Control Register.
-//
-//****************************************************************************
-#define PCPCR_EN                               0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the debug index register.
-//
-//****************************************************************************
-#define DREG_REGID_MASK                         0x0000007FL
-#define DREG_DEBUG                              0x00000080L
-#define DREG_RGBK_MASK                          0x00000700L
-#define DREG_TRAP                               0x00000800L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_TRAPX                              0x00001000L
-#endif
-#endif
-#define DREG_REGID_SHIFT                        0L
-#define DREG_RGBK_SHIFT                         8L
-#define DREG_RGBK_REGID_MASK                    0x0000077FL
-#define DREG_REGID_R0                           0x00000010L
-#define DREG_REGID_R1                           0x00000011L
-#define DREG_REGID_R2                           0x00000012L
-#define DREG_REGID_R3                           0x00000013L
-#define DREG_REGID_R4                           0x00000014L
-#define DREG_REGID_R5                           0x00000015L
-#define DREG_REGID_R6                           0x00000016L
-#define DREG_REGID_R7                           0x00000017L
-#define DREG_REGID_R8                           0x00000018L
-#define DREG_REGID_R9                           0x00000019L
-#define DREG_REGID_RA                           0x0000001AL
-#define DREG_REGID_RB                           0x0000001BL
-#define DREG_REGID_RC                           0x0000001CL
-#define DREG_REGID_RD                           0x0000001DL
-#define DREG_REGID_RE                           0x0000001EL
-#define DREG_REGID_RF                           0x0000001FL
-#define DREG_REGID_RA_BUS_LOW                   0x00000020L
-#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
-#define DREG_REGID_YBUS_LOW                     0x00000050L
-#define DREG_REGID_YBUS_HIGH                    0x00000058L
-#define DREG_REGID_TRAP_0                       0x00000100L
-#define DREG_REGID_TRAP_1                       0x00000101L
-#define DREG_REGID_TRAP_2                       0x00000102L
-#define DREG_REGID_TRAP_3                       0x00000103L
-#define DREG_REGID_TRAP_4                       0x00000104L
-#define DREG_REGID_TRAP_5                       0x00000105L
-#define DREG_REGID_TRAP_6                       0x00000106L
-#define DREG_REGID_TRAP_7                       0x00000107L
-#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
-#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_8                       0x00000110L
-#define DREG_REGID_TRAP_9                       0x00000111L
-#define DREG_REGID_TRAP_10                      0x00000112L
-#define DREG_REGID_TRAP_11                      0x00000113L
-#define DREG_REGID_TRAP_12                      0x00000114L
-#define DREG_REGID_TRAP_13                      0x00000115L
-#define DREG_REGID_TRAP_14                      0x00000116L
-#define DREG_REGID_TRAP_15                      0x00000117L
-#define DREG_REGID_TRAP_16                      0x00000118L
-#define DREG_REGID_TRAP_17                      0x00000119L
-#define DREG_REGID_TRAP_18                      0x0000011AL
-#define DREG_REGID_TRAP_19                      0x0000011BL
-#define DREG_REGID_TRAP_20                      0x0000011CL
-#define DREG_REGID_TRAP_21                      0x0000011DL
-#define DREG_REGID_TRAP_22                      0x0000011EL
-#define DREG_REGID_TRAP_23                      0x0000011FL
-#endif
-#endif
-#define DREG_REGID_RSA0_LOW                     0x00000200L
-#define DREG_REGID_RSA0_HIGH                    0x00000201L
-#define DREG_REGID_RSA1_LOW                     0x00000202L
-#define DREG_REGID_RSA1_HIGH                    0x00000203L
-#define DREG_REGID_RSA2                         0x00000204L
-#define DREG_REGID_RSA3                         0x00000205L
-#define DREG_REGID_RSI0_LOW                     0x00000206L
-#define DREG_REGID_RSI0_HIGH                    0x00000207L
-#define DREG_REGID_RSI1                         0x00000208L
-#define DREG_REGID_RSI2                         0x00000209L
-#define DREG_REGID_SAGUSTATUS                   0x0000020AL
-#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
-#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
-#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
-#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
-#define DREG_REGID_RSDMA01E                     0x0000020FL
-#define DREG_REGID_RSDMA23E                     0x00000210L
-#define DREG_REGID_RSD0_LOW                     0x00000211L
-#define DREG_REGID_RSD0_HIGH                    0x00000212L
-#define DREG_REGID_RSD1_LOW                     0x00000213L
-#define DREG_REGID_RSD1_HIGH                    0x00000214L
-#define DREG_REGID_RSD2_LOW                     0x00000215L
-#define DREG_REGID_RSD2_HIGH                    0x00000216L
-#define DREG_REGID_RSD3_LOW                     0x00000217L
-#define DREG_REGID_RSD3_HIGH                    0x00000218L
-#define DREG_REGID_SRAR_HIGH                    0x0000021AL
-#define DREG_REGID_SRAR_LOW                     0x0000021BL
-#define DREG_REGID_DMA_STATE                    0x0000021CL
-#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
-#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
-#define DREG_REGID_CPU_STATUS                   0x00000300L
-#define DREG_REGID_MAC_MODE                     0x00000301L
-#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
-#define DREG_REGID_INDEX0                       0x00000304L
-#define DREG_REGID_INDEX1                       0x00000305L
-#define DREG_REGID_DMA_STATE_0_3                0x00000400L
-#define DREG_REGID_DMA_STATE_4_7                0x00000404L
-#define DREG_REGID_DMA_STATE_8_11               0x00000408L
-#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
-#define DREG_REGID_DMA_STATE_16_19              0x00000410L
-#define DREG_REGID_DMA_STATE_20_23              0x00000414L
-#define DREG_REGID_DMA_STATE_24_27              0x00000418L
-#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
-#define DREG_REGID_DMA_STATE_32_35              0x00000420L
-#define DREG_REGID_DMA_STATE_36_39              0x00000424L
-#define DREG_REGID_DMA_STATE_40_43              0x00000428L
-#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
-#define DREG_REGID_DMA_STATE_48_51              0x00000430L
-#define DREG_REGID_DMA_STATE_52_55              0x00000434L
-#define DREG_REGID_DMA_STATE_56_59              0x00000438L
-#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
-#define DREG_REGID_DMA_STATE_64_67              0x00000440L
-#define DREG_REGID_DMA_STATE_68_71              0x00000444L
-#define DREG_REGID_DMA_STATE_72_75              0x00000448L
-#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
-#define DREG_REGID_DMA_STATE_80_83              0x00000450L
-#define DREG_REGID_DMA_STATE_84_87              0x00000454L
-#define DREG_REGID_DMA_STATE_88_91              0x00000458L
-#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
-#define DREG_REGID_TRAP_SELECT                  0x00000500L
-#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
-#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
-#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
-#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
-#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
-#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
-#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
-#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
-#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
-#define DREG_REGID_TRAP_WRITE_10                0x00000512L
-#define DREG_REGID_TRAP_WRITE_11                0x00000513L
-#define DREG_REGID_TRAP_WRITE_12                0x00000514L
-#define DREG_REGID_TRAP_WRITE_13                0x00000515L
-#define DREG_REGID_TRAP_WRITE_14                0x00000516L
-#define DREG_REGID_TRAP_WRITE_15                0x00000517L
-#define DREG_REGID_TRAP_WRITE_16                0x00000518L
-#define DREG_REGID_TRAP_WRITE_17                0x00000519L
-#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
-#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
-#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
-#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
-#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
-#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
-#endif
-#endif
-#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
-#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
-#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
-#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
-#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
-#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
-#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
-#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
-#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
-#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
-#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
-#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
-#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
-#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
-#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
-#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
-#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
-#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
-#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
-#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
-#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
-#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
-#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
-#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
-#define DREG_REGID_RSHOUT_LOW                   0x00000620L
-#define DREG_REGID_RSHOUT_MID                   0x00000628L
-#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 S/PDIF Control register.
-//
-//****************************************************************************
-#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
-#define SPDIF_CONTROL_VAL                      0x00004000L
-#define SPDIF_CONTROL_COPY                     0x00000004L
-#define SPDIF_CONTROL_CC0                      0x00000010L
-#define SPDIF_CONTROL_CC1                      0x00000020L
-#define SPDIF_CONTROL_CC2                      0x00000040L
-#define SPDIF_CONTROL_CC3                      0x00000080L
-#define SPDIF_CONTROL_CC4                      0x00000100L
-#define SPDIF_CONTROL_CC5                      0x00000200L
-#define SPDIF_CONTROL_CC6                      0x00000400L
-#define SPDIF_CONTROL_L                        0x00000800L
-
-#endif // _H_HWDEFS
diff --git a/sound/oss/cs4281/cs4281_wrapper-24.c b/sound/oss/cs4281/cs4281_wrapper-24.c
deleted file mode 100644 (file)
index 4559f02..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281_wrapper.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/20/00 trw - new file. 
-*
-*******************************************************************************/
-
-#include <linux/spinlock.h>
-
-static int cs4281_resume_null(struct pci_dev *pcidev) { return 0; }
-static int cs4281_suspend_null(struct pci_dev *pcidev, pm_message_t state) { return 0; }
-
-#define free_dmabuf(state, dmabuf) \
-       pci_free_consistent(state->pcidev, \
-                           PAGE_SIZE << (dmabuf)->buforder, \
-                           (dmabuf)->rawbuf, (dmabuf)->dmaaddr);
-#define free_dmabuf2(state, dmabuf) \
-       pci_free_consistent((state)->pcidev, \
-                                   PAGE_SIZE << (state)->buforder_tmpbuff, \
-                                   (state)->tmpbuff, (state)->dmaaddr_tmpbuff);
-#define cs4x_pgoff(vma) ((vma)->vm_pgoff)
-
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
deleted file mode 100644 (file)
index 0400a41..0000000
+++ /dev/null
@@ -1,4487 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- adapted from drivers by Thomas Sailer, 
-*            -- but don't bug him; Problems should go to:
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Module command line parameters:
-*   none
-*
-*  Supported devices:
-*  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
-*  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
-*  /dev/midi   simple MIDI UART interface, no ioctl
-*
-* Modification History
-* 08/20/00 trw - silence and no stopping DAC until release
-* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
-* 09/18/00 trw - added 16bit only record with conversion 
-* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
-*                capture/playback rates)
-* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
-*                libOSSm.so)
-* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
-* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
-* 11/10/00 bkz - added __devinit to cs4281_hw_init()
-* 11/10/00 trw - fixed SMP and capture spinlock hang.
-* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
-* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
-* 12/08/00 trw - added PM support. 
-* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 
-*               (RH/Dell base), 2.2.18, 2.2.12.  cleaned up code mods by ident.
-* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
-* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use 
-*               defaultorder-100 as power of 2 for the buffer size. example:
-*               106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*
-*******************************************************************************/
-
-/* uncomment the following line to disable building PM support into the driver */
-//#define NOT_CS4281_PM 1 
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/fs.h>
-#include <linux/wait.h>
-
-#include <asm/current.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-//#include "cs_dm.h"
-#include "cs4281_hwdefs.h"
-#include "cs4281pm.h"
-
-struct cs4281_state;
-
-static void stop_dac(struct cs4281_state *s);
-static void stop_adc(struct cs4281_state *s);
-static void start_dac(struct cs4281_state *s);
-static void start_adc(struct cs4281_state *s);
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-// --------------------------------------------------------------------- 
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS          0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
-#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
-#endif
-
-#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
-#define        CS4281_CFLR_DEFAULT     0x00000001  /* CFLR must be in AC97 link mode */
-
-// buffer order determines the size of the dma buffer for the driver.
-// under Linux, a smaller buffer allows more responsiveness from many of the 
-// applications (e.g. games).  A larger buffer allows some of the apps (esound) 
-// to not underrun the dma buffer as easily.  As default, use 32k (order=3)
-// rather than 64k as some of the games work more responsively.
-// log base 2( buff sz = 32k).
-static unsigned long defaultorder = 3;
-module_param(defaultorder, ulong, 0);
-
-//
-// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
-//
-#define CSDEBUG 1
-#if CSDEBUG
-#define CSDEBUG_INTERFACE 1
-#else
-#undef CSDEBUG_INTERFACE
-#endif
-//
-// cs_debugmask areas
-//
-#define CS_INIT                0x00000001      // initialization and probe functions
-#define CS_ERROR       0x00000002      // tmp debugging bit placeholder
-#define CS_INTERRUPT   0x00000004      // interrupt handler (separate from all other)
-#define CS_FUNCTION    0x00000008      // enter/leave functions
-#define CS_WAVE_WRITE  0x00000010      // write information for wave
-#define CS_WAVE_READ   0x00000020      // read information for wave
-#define CS_MIDI_WRITE  0x00000040      // write information for midi
-#define CS_MIDI_READ   0x00000080      // read information for midi
-#define CS_MPU401_WRITE 0x00000100     // write information for mpu401
-#define CS_MPU401_READ         0x00000200      // read information for mpu401
-#define CS_OPEN                0x00000400      // all open functions in the driver
-#define CS_RELEASE     0x00000800      // all release functions in the driver
-#define CS_PARMS       0x00001000      // functional and operational parameters
-#define CS_IOCTL       0x00002000      // ioctl (non-mixer)
-#define CS_PM          0x00004000      // power management 
-#define CS_TMP         0x10000000      // tmp debug mask bit
-
-#define CS_IOCTL_CMD_SUSPEND   0x1     // suspend
-#define CS_IOCTL_CMD_RESUME    0x2     // resume
-//
-// CSDEBUG is usual mode is set to 1, then use the
-// cs_debuglevel and cs_debugmask to turn on or off debugging.
-// Debug level of 1 has been defined to be kernel errors and info
-// that should be printed on any released driver.
-//
-#if CSDEBUG
-#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
-#else
-#define CS_DBGOUT(mask,level,x)
-#endif
-
-#if CSDEBUG
-static unsigned long cs_debuglevel = 1;        // levels range from 1-9
-static unsigned long cs_debugmask = CS_INIT | CS_ERROR;        // use CS_DBGOUT with various mask values
-module_param(cs_debuglevel, ulong, 0);
-module_param(cs_debugmask, ulong, 0);
-#endif
-#define CS_TRUE        1
-#define CS_FALSE       0
-
-// MIDI buffer sizes 
-#define MIDIINBUF  500
-#define MIDIOUTBUF 500
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define CS4281_MAJOR_VERSION   1
-#define CS4281_MINOR_VERSION   13
-#ifdef __ia64__
-#define CS4281_ARCH            64      //architecture key
-#else
-#define CS4281_ARCH            32      //architecture key
-#endif
-
-#define CS_TYPE_ADC 0
-#define CS_TYPE_DAC 1
-
-
-static const char invalid_magic[] =
-    KERN_CRIT "cs4281: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-        if (!(s) || (s)->magic != CS4281_MAGIC) { \
-                printk(invalid_magic);            \
-                return -ENXIO;                    \
-        }                                         \
-})
-
-//LIST_HEAD(cs4281_devs);
-static struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
-
-struct cs4281_state; 
-
-#include "cs4281_wrapper-24.c"
-
-struct cs4281_state {
-       // magic 
-       unsigned int magic;
-
-       // we keep the cards in a linked list 
-       struct cs4281_state *next;
-
-       // pcidev is needed to turn off the DDMA controller at driver shutdown 
-       struct pci_dev *pcidev;
-       struct list_head list;
-
-       // soundcore stuff 
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-
-       // hardware resources 
-       unsigned int pBA0phys, pBA1phys;
-       char __iomem *pBA0;
-       char __iomem *pBA1;
-       unsigned int irq;
-
-       // mixer registers 
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-       } mix;
-
-       // wave stuff   
-       struct properties {
-               unsigned fmt;
-               unsigned fmt_original;  // original requested format
-               unsigned channels;
-               unsigned rate;
-               unsigned char clkdiv;
-       } prop_dac, prop_adc;
-       unsigned conversion:1;  // conversion from 16 to 8 bit in progress
-       void *tmpbuff;          // tmp buffer for sample conversions
-       unsigned ena;
-       spinlock_t lock;
-       struct mutex open_sem;
-       struct mutex open_sem_adc;
-       struct mutex open_sem_dac;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-       wait_queue_head_t open_wait_adc;
-       wait_queue_head_t open_wait_dac;
-
-       dma_addr_t dmaaddr_tmpbuff;
-       unsigned buforder_tmpbuff;      // Log base 2 of 'rawbuf' size in bytes..
-       struct dmabuf {
-               void *rawbuf;   // Physical address of  
-               dma_addr_t dmaaddr;
-               unsigned buforder;      // Log base 2 of 'rawbuf' size in bytes..
-               unsigned numfrag;       // # of 'fragments' in the buffer.
-               unsigned fragshift;     // Log base 2 of fragment size.
-               unsigned hwptr, swptr;
-               unsigned total_bytes;   // # bytes process since open.
-               unsigned blocks;        // last returned blocks value GETOPTR
-               unsigned wakeup;        // interrupt occurred on block 
-               int count;
-               unsigned underrun;      // underrun flag
-               unsigned error; // over/underrun 
-               wait_queue_head_t wait;
-               // redundant, but makes calculations easier 
-               unsigned fragsize;      // 2**fragshift..
-               unsigned dmasize;       // 2**buforder.
-               unsigned fragsamples;
-               // OSS stuff 
-               unsigned mapped:1;      // Buffer mapped in cs4281_mmap()?
-               unsigned ready:1;       // prog_dmabuf_dac()/adc() successful?
-               unsigned endcleared:1;
-               unsigned type:1;        // adc or dac buffer (CS_TYPE_XXX)
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       // midi stuff 
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-       struct cs4281_pm pm;
-       struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
-};
-
-#include "cs4281pm-24.c"
-
-#if CSDEBUG
-
-// DEBUG ROUTINES
-
-#define SOUND_MIXER_CS_GETDBGLEVEL     _SIOWR('M',120, int)
-#define SOUND_MIXER_CS_SETDBGLEVEL     _SIOWR('M',121, int)
-#define SOUND_MIXER_CS_GETDBGMASK      _SIOWR('M',122, int)
-#define SOUND_MIXER_CS_SETDBGMASK      _SIOWR('M',123, int)
-
-#define SOUND_MIXER_CS_APM             _SIOWR('M',124, int)
-
-
-static void cs_printioctl(unsigned int x)
-{
-       unsigned int i;
-       unsigned char vidx;
-       // Index of mixtable1[] member is Device ID 
-       // and must be <= SOUND_MIXER_NRDEVICES.
-       // Value of array member is index into s->mix.vol[]
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM] = 1,  // voice 
-               [SOUND_MIXER_LINE1] = 2,        // AUX
-               [SOUND_MIXER_CD] = 3,   // CD 
-               [SOUND_MIXER_LINE] = 4, // Line 
-               [SOUND_MIXER_SYNTH] = 5,        // FM
-               [SOUND_MIXER_MIC] = 6,  // Mic 
-               [SOUND_MIXER_SPEAKER] = 7,      // Speaker 
-               [SOUND_MIXER_RECLEV] = 8,       // Recording level 
-               [SOUND_MIXER_VOLUME] = 9        // Master Volume 
-       };
-
-       switch (x) {
-       case SOUND_MIXER_CS_GETDBGMASK:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
-               break;
-       case SOUND_MIXER_CS_GETDBGLEVEL:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
-               break;
-       case SOUND_MIXER_CS_SETDBGMASK:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
-               break;
-       case SOUND_MIXER_CS_SETDBGLEVEL:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
-               break;
-       case OSS_GETVERSION:
-               CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
-               break;
-       case SNDCTL_DSP_SYNC:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
-               break;
-       case SNDCTL_DSP_SETDUPLEX:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
-               break;
-       case SNDCTL_DSP_GETCAPS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
-               break;
-       case SNDCTL_DSP_RESET:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
-               break;
-       case SNDCTL_DSP_SPEED:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
-               break;
-       case SNDCTL_DSP_STEREO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
-               break;
-       case SNDCTL_DSP_CHANNELS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
-               break;
-       case SNDCTL_DSP_GETFMTS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
-               break;
-       case SNDCTL_DSP_SETFMT:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
-               break;
-       case SNDCTL_DSP_POST:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
-               break;
-       case SNDCTL_DSP_GETTRIGGER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
-               break;
-       case SNDCTL_DSP_SETTRIGGER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
-               break;
-       case SNDCTL_DSP_GETOSPACE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
-               break;
-       case SNDCTL_DSP_GETISPACE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
-               break;
-       case SNDCTL_DSP_NONBLOCK:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
-               break;
-       case SNDCTL_DSP_GETODELAY:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
-               break;
-       case SNDCTL_DSP_GETIPTR:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
-               break;
-       case SNDCTL_DSP_GETOPTR:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
-               break;
-       case SNDCTL_DSP_GETBLKSIZE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
-               break;
-       case SNDCTL_DSP_SETFRAGMENT:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SNDCTL_DSP_SETFRAGMENT:\n"));
-               break;
-       case SNDCTL_DSP_SUBDIVIDE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
-               break;
-       case SOUND_PCM_READ_RATE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
-               break;
-       case SOUND_PCM_READ_CHANNELS:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_PCM_READ_CHANNELS:\n"));
-               break;
-       case SOUND_PCM_READ_BITS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
-               break;
-       case SOUND_PCM_WRITE_FILTER:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_PCM_WRITE_FILTER:\n"));
-               break;
-       case SNDCTL_DSP_SETSYNCRO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
-               break;
-       case SOUND_PCM_READ_FILTER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE1:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE2:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE3:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE4:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE5:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
-               break;
-       case SOUND_MIXER_INFO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
-               break;
-       case SOUND_OLD_MIXER_INFO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
-               break;
-
-       default:
-               switch (_IOC_NR(x)) {
-               case SOUND_MIXER_VOLUME:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_VOLUME:\n"));
-                       break;
-               case SOUND_MIXER_SPEAKER:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_SPEAKER:\n"));
-                       break;
-               case SOUND_MIXER_RECLEV:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECLEV:\n"));
-                       break;
-               case SOUND_MIXER_MIC:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_MIC:\n"));
-                       break;
-               case SOUND_MIXER_SYNTH:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_SYNTH:\n"));
-                       break;
-               case SOUND_MIXER_RECSRC:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECSRC:\n"));
-                       break;
-               case SOUND_MIXER_DEVMASK:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_DEVMASK:\n"));
-                       break;
-               case SOUND_MIXER_RECMASK:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECMASK:\n"));
-                       break;
-               case SOUND_MIXER_STEREODEVS:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_STEREODEVS:\n"));
-                       break;
-               case SOUND_MIXER_CAPS:
-                       CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
-                       break;
-               default:
-                       i = _IOC_NR(x);
-                       if (i >= SOUND_MIXER_NRDEVICES
-                           || !(vidx = mixtable1[i])) {
-                               CS_DBGOUT(CS_IOCTL, 4, printk
-                                       ("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
-                                               x, i));
-                       } else {
-                               CS_DBGOUT(CS_IOCTL, 4, printk
-                                       ("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
-                                               x, i));
-                       }
-                       break;
-               }
-       }
-}
-#endif
-static int prog_dmabuf_adc(struct cs4281_state *s);
-static void prog_codec(struct cs4281_state *s, unsigned type);
-
-// --------------------------------------------------------------------- 
-//
-//              Hardware Interfaces For the CS4281
-//
-
-
-//******************************************************************************
-// "delayus()-- Delay for the specified # of microseconds.
-//******************************************************************************
-static void delayus(struct cs4281_state *s, u32 delay)
-{
-       u32 j;
-       if ((delay > 9999) && (s->pm.flags & CS4281_PM_IDLE)) {
-               j = (delay * HZ) / 1000000;     /* calculate delay in jiffies  */
-               if (j < 1)
-                       j = 1;  /* minimum one jiffy. */
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout(j);
-       } else
-               udelay(delay);
-       return;
-}
-
-
-//******************************************************************************
-// "cs4281_read_ac97" -- Reads a word from the specified location in the
-//               CS4281's address space(based on the BA0 register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
-//                                            0h for reads.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
-// 5. if DCV not cleared, break and return error
-// 6. Read ACSTS = Status Register = 464h, check VSTS bit
-//****************************************************************************
-static int cs4281_read_ac97(struct cs4281_state *card, u32 offset,
-                           u32 * value)
-{
-       u32 count, status;
-
-       // Make sure that there is not data sitting
-       // around from a previous uncompleted access.
-       // ACSDA = Status Data Register = 47Ch
-       status = readl(card->pBA0 + BA0_ACSDA);
-
-       // Setup the AC97 control registers on the CS4281 to send the
-       // appropriate command to the AC97 to perform the read.
-       // ACCAD = Command Address Register = 46Ch
-       // ACCDA = Command Data Register = 470h
-       // ACCTL = Control Register = 460h
-       // bit DCV - will clear when process completed
-       // bit CRW - Read command
-       // bit VFRM - valid frame enabled
-       // bit ESYN - ASYNC generation enabled
-
-       // Get the actual AC97 register from the offset
-       writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-       writel(0, card->pBA0 + BA0_ACCDA);
-       writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,
-              card->pBA0 + BA0_ACCTL);
-
-       // Wait for the read to occur.
-       for (count = 0; count < 10; count++) {
-               // First, we want to wait for a short time.
-               udelay(25);
-
-               // Now, check to see if the read has completed.
-               // ACCTL = 460h, DCV should be reset by now and 460h = 17h
-               if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV))
-                       break;
-       }
-
-       // Make sure the read completed.
-       if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)
-               return 1;
-
-       // Wait for the valid status bit to go active.
-       for (count = 0; count < 10; count++) {
-               // Read the AC97 status register.
-               // ACSTS = Status Register = 464h
-               status = readl(card->pBA0 + BA0_ACSTS);
-
-               // See if we have valid status.
-               // VSTS - Valid Status
-               if (status & ACSTS_VSTS)
-                       break;
-               // Wait for a short while.
-               udelay(25);
-       }
-
-       // Make sure we got valid status.
-       if (!(status & ACSTS_VSTS))
-               return 1;
-
-       // Read the data returned from the AC97 register.
-       // ACSDA = Status Data Register = 474h
-       *value = readl(card->pBA0 + BA0_ACSDA);
-
-       // Success.
-       return (0);
-}
-
-
-//****************************************************************************
-//
-// "cs4281_write_ac97()"-- writes a word to the specified location in the
-// CS461x's address space (based on the part's base address zero register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
-// 5. if DCV not cleared, break and return error
-//
-//****************************************************************************
-static int cs4281_write_ac97(struct cs4281_state *card, u32 offset,
-                            u32 value)
-{
-       u32 count, status=0;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n"));
-
-       // Setup the AC97 control registers on the CS4281 to send the
-       // appropriate command to the AC97 to perform the read.
-       // ACCAD = Command Address Register = 46Ch
-       // ACCDA = Command Data Register = 470h
-       // ACCTL = Control Register = 460h
-       // set DCV - will clear when process completed
-       // reset CRW - Write command
-       // set VFRM - valid frame enabled
-       // set ESYN - ASYNC generation enabled
-       // set RSTN - ARST# inactive, AC97 codec not reset
-
-       // Get the actual AC97 register from the offset
-
-       writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-       writel(value, card->pBA0 + BA0_ACCDA);
-       writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN,
-              card->pBA0 + BA0_ACCTL);
-
-       // Wait for the write to occur.
-       for (count = 0; count < 100; count++) {
-               // First, we want to wait for a short time.
-               udelay(25);
-               // Now, check to see if the write has completed.
-               // ACCTL = 460h, DCV should be reset by now and 460h = 07h
-               status = readl(card->pBA0 + BA0_ACCTL);
-               if (!(status & ACCTL_DCV))
-                       break;
-       }
-
-       // Make sure the write completed.
-       if (status & ACCTL_DCV) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                       "cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n"));
-               return 1;
-       }
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n"));
-       // Success.
-       return 0;
-}
-
-
-//******************************************************************************
-// "Init4281()" -- Bring up the part.
-//******************************************************************************
-static __devinit int cs4281_hw_init(struct cs4281_state *card)
-{
-       u32 ac97_slotid;
-       u32 temp1, temp2;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n"));
-#ifndef NOT_CS4281_PM
-       if(!card)
-               return 1;
-#endif
-       temp2 = readl(card->pBA0 + BA0_CFLR);
-       CS_DBGOUT(CS_INIT | CS_ERROR | CS_PARMS, 4, printk(KERN_INFO 
-               "cs4281: cs4281_hw_init() CFLR 0x%x\n", temp2));
-       if(temp2 != CS4281_CFLR_DEFAULT)
-       {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-                       "cs4281: cs4281_hw_init() CFLR invalid - resetting from 0x%x to 0x%x\n",
-                               temp2,CS4281_CFLR_DEFAULT));
-               writel(CS4281_CFLR_DEFAULT, card->pBA0 + BA0_CFLR);
-               temp2 = readl(card->pBA0 + BA0_CFLR);
-               if(temp2 != CS4281_CFLR_DEFAULT)
-               {
-                       CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-                               "cs4281: cs4281_hw_init() Invalid hardware - unable to configure CFLR\n"));
-                       return 1;
-               }
-       }
-
-       //***************************************7
-       //  Set up the Sound System Configuration
-       //***************************************
-
-       // Set the 'Configuration Write Protect' register
-       // to 4281h.  Allows vendor-defined configuration
-       // space between 0e4h and 0ffh to be written.
-
-       writel(0x4281, card->pBA0 + BA0_CWPR);  // (3e0h)
-
-       // (0), Blast the clock control register to zero so that the
-       // PLL starts out in a known state, and blast the master serial
-       // port control register to zero so that the serial ports also
-       // start out in a known state.
-
-       writel(0, card->pBA0 + BA0_CLKCR1);     // (400h)
-       writel(0, card->pBA0 + BA0_SERMC);      // (420h)
-
-
-       // (1), Make ESYN go to zero to turn off
-       // the Sync pulse on the AC97 link.
-
-       writel(0, card->pBA0 + BA0_ACCTL);
-       udelay(50);
-
-
-       // (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
-       // the AC97 spec) and then drive it high.  This is done for non
-       // AC97 modes since there might be logic external to the CS461x
-       // that uses the ARST# line for a reset.
-
-       writel(0, card->pBA0 + BA0_SPMC);       // (3ech)
-       udelay(100);
-       writel(SPMC_RSTN, card->pBA0 + BA0_SPMC);
-       delayus(card,50000);            // Wait 50 ms for ABITCLK to become stable.
-
-       // (3) Turn on the Sound System Clocks.
-       writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1);   // (400h)
-       delayus(card,50000);            // Wait for the PLL to stabilize.
-       // Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
-       writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1);
-
-       // (4) Power on everything for now..
-       writel(0x7E, card->pBA0 + BA0_SSPM);    // (740h)
-
-       // (5) Wait for clock stabilization.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               udelay(1000);
-               if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)
-                       break;
-       }
-       if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR 
-                       "cs4281: DLLRDY failed!\n"));
-               return -EIO;
-       }
-       // (6) Enable ASYNC generation.
-       writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL);     // (460h)
-
-       // Now wait 'for a short while' to allow the  AC97
-       // part to start generating bit clock. (so we don't
-       // Try to start the PLL without an input clock.)
-       delayus(card,50000);
-
-       // Set the serial port timing configuration, so that the
-       // clock control circuit gets its clock from the right place.
-       writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2.
-
-       // (7) Wait for the codec ready signal from the AC97 codec.
-
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               // Delay a mil to let things settle out and
-               // to prevent retrying the read too quickly.
-               udelay(1000);
-               if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY) // If ready,  (464h)
-                       break;  //   exit the 'for' loop.
-       }
-       if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY))      // If never came ready,
-       {
-               CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-                        "cs4281: ACSTS never came ready!\n"));
-               return -EIO;    //   exit initialization.
-       }
-       // (8) Assert the 'valid frame' signal so we can
-       // begin sending commands to the AC97 codec.
-       writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL);        // (460h)
-
-       // (9), Wait until CODEC calibration is finished.
-       // Print an error message if it doesn't.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               delayus(card,10000);
-               // Read the AC97 Powerdown Control/Status Register.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
-               if ((temp2 & 0x0000000F) == 0x0000000F)
-                       break;
-       }
-       if ((temp2 & 0x0000000F) != 0x0000000F) {
-               CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-                       "cs4281: Codec failed to calibrate.  Status = %.8x.\n",
-                               temp2));
-               return -EIO;
-       }
-       // (10), Set the serial port timing configuration, so that the
-       // clock control circuit gets its clock from the right place.
-       writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2.
-
-
-       // (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
-       // that the codec is pumping ADC data across the AC link.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               // Delay a mil to let things settle out and
-               // to prevent retrying the read too quickly.
-               delayus(card,1000);     //(test)
-
-               // Read the input slot valid register;  See
-               // if input slots 3 and 4 are valid yet.
-               if (
-                   (readl(card->pBA0 + BA0_ACISV) &
-                    (ACISV_ISV3 | ACISV_ISV4)) ==
-                   (ACISV_ISV3 | ACISV_ISV4)) break;   // Exit the 'for' if slots are valid.
-       }
-       // If we never got valid data, exit initialization.
-       if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4))
-           != (ACISV_ISV3 | ACISV_ISV4)) {
-               CS_DBGOUT(CS_FUNCTION, 2,
-                         printk(KERN_ERR
-                                "cs4281: Never got valid data!\n"));
-               return -EIO;    // If no valid data, exit initialization.
-       }
-       // (12), Start digital data transfer of audio data to the codec.
-       writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV);        // (468h)
-
-
-       //**************************************
-       // Unmute the Master and Alternate
-       // (headphone) volumes.  Set to max.
-       //**************************************
-       cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0);
-       cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0);
-
-       //******************************************
-       // Power on the DAC(AddDACUser()from main())
-       //******************************************
-       cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-       cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
-
-       // Wait until we sample a DAC ready state.
-       for (temp2 = 0; temp2 < 32; temp2++) {
-               // Let's wait a mil to let things settle.
-               delayus(card,1000);
-               // Read the current state of the power control reg.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-               // If the DAC ready state bit is set, stop waiting.
-               if (temp1 & 0x2)
-                       break;
-       }
-
-       //******************************************
-       // Power on the ADC(AddADCUser()from main())
-       //******************************************
-       cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-       cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
-
-       // Wait until we sample ADC ready state.
-       for (temp2 = 0; temp2 < 32; temp2++) {
-               // Let's wait a mil to let things settle.
-               delayus(card,1000);
-               // Read the current state of the power control reg.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-               // If the ADC ready state bit is set, stop waiting.
-               if (temp1 & 0x1)
-                       break;
-       }
-       // Set up 4281 Register contents that
-       // don't change for boot duration.
-
-       // For playback, we map AC97 slot 3 and 4(Left
-       // & Right PCM playback) to DMA Channel 0.
-       // Set the fifo to be 15 bytes at offset zero.
-
-       ac97_slotid = 0x01000f00;       // FCR0.RS[4:0]=1(=>slot4, right PCM playback).
-       // FCR0.LS[4:0]=0(=>slot3, left PCM playback).
-       // FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
-       writel(ac97_slotid, card->pBA0 + BA0_FCR0);     // (180h)
-       writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);  // Turn on FIFO Enable.
-
-       // For capture, we map AC97 slot 10 and 11(Left
-       // and Right PCM Record) to DMA Channel 1.
-       // Set the fifo to be 15 bytes at offset sixteen.
-       ac97_slotid = 0x0B0A0f10;       // FCR1.RS[4:0]=11(=>slot11, right PCM record).
-       // FCR1.LS[4:0]=10(=>slot10, left PCM record).
-       // FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
-       writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);  // (184h)
-       writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);  // Turn on FIFO Enable.
-
-       // Map the Playback SRC to the same AC97 slots(3 & 4--
-       // --Playback left & right)as DMA channel 0.
-       // Map the record SRC to the same AC97 slots(10 & 11--
-       // -- Record left & right) as DMA channel 1.
-
-       ac97_slotid = 0x0b0a0100;       // SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
-       // SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
-       // SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
-       // SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
-       writel(ac97_slotid, card->pBA0 + BA0_SRCSA);    // (75ch)
-
-       // Set 'Half Terminal Count Interrupt Enable' and 'Terminal
-       // Count Interrupt Enable' in DMA Control Registers 0 & 1.
-       // Set 'MSK' flag to 1 to keep the DMA engines paused.
-       temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);    // (00030001h)
-       writel(temp1, card->pBA0 + BA0_DCR0);   // (154h
-       writel(temp1, card->pBA0 + BA0_DCR1);   // (15ch)
-
-       // Set 'Auto-Initialize Control' to 'enabled'; For playback,
-       // set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
-       // for record, set Transfer Type Control to 'write transfer'.
-       // All other bits set to zero;  Some will be changed @ transfer start.
-       temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);  // (20000018h)
-       writel(temp1, card->pBA0 + BA0_DMR0);   // (150h)
-       temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); // (20000014h)
-       writel(temp1, card->pBA0 + BA0_DMR1);   // (158h)
-
-       // Enable DMA interrupts generally, and
-       // DMA0 & DMA1 interrupts specifically.
-       temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
-       writel(temp1, card->pBA0 + BA0_HIMR);
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n"));
-       return 0;
-}
-
-#ifndef NOT_CS4281_PM
-static void printpm(struct cs4281_state *s)
-{
-       CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-       CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
-               (unsigned)s->pm.flags,s->pm.u32CLKCR1_SAVE,s->pm.u32SSPMValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32PPLVCvalue: 0x%x u32PPRVCvalue: 0x%x\n",
-               s->pm.u32PPLVCvalue,s->pm.u32PPRVCvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32FMLVCvalue: 0x%x u32FMRVCvalue: 0x%x\n",
-               s->pm.u32FMLVCvalue,s->pm.u32FMRVCvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32GPIORvalue: 0x%x u32JSCTLvalue: 0x%x\n",
-               s->pm.u32GPIORvalue,s->pm.u32JSCTLvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32SSCR: 0x%x u32SRCSA: 0x%x\n",
-               s->pm.u32SSCR,s->pm.u32SRCSA));
-       CS_DBGOUT(CS_PM, 9, printk("u32DacASR: 0x%x u32AdcASR: 0x%x\n",
-               s->pm.u32DacASR,s->pm.u32AdcASR));
-       CS_DBGOUT(CS_PM, 9, printk("u32DacSR: 0x%x u32AdcSR: 0x%x\n",
-               s->pm.u32DacSR,s->pm.u32AdcSR));
-       CS_DBGOUT(CS_PM, 9, printk("u32MIDCR_Save: 0x%x\n",
-               s->pm.u32MIDCR_Save));
-
-}
-static void printpipe(struct cs4281_pipeline *pl)
-{
-
-       CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-       CS_DBGOUT(CS_PM, 9, printk("flags:0x%x number: 0%x\n",
-               (unsigned)pl->flags,pl->number));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBAnValue: 0%x u32DBCnValue: 0x%x\n",
-               pl->u32DBAnValue,pl->u32DBCnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32DMRnValue: 0x%x u32DCRnValue: 0x%x\n",
-               pl->u32DMRnValue,pl->u32DCRnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBAnAddress: 0x%x u32DBCnAddress: 0x%x\n",
-               pl->u32DBAnAddress,pl->u32DBCnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCAnAddress: 0x%x u32DCCnAddress: 0x%x\n",
-               pl->u32DCCnAddress,pl->u32DCCnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32DMRnAddress: 0x%x u32DCRnAddress: 0x%x\n",
-               pl->u32DMRnAddress,pl->u32DCRnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32HDSRnAddress: 0x%x u32DBAn_Save: 0x%x\n",
-               pl->u32HDSRnAddress,pl->u32DBAn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBCn_Save: 0x%x u32DMRn_Save: 0x%x\n",
-               pl->u32DBCn_Save,pl->u32DMRn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCRn_Save: 0x%x u32DCCn_Save: 0x%x\n",
-               pl->u32DCRn_Save,pl->u32DCCn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCAn_Save: 0x%x\n",
-               pl->u32DCAn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRn_Save: 0x%x u32FSICn_Save: 0x%x\n",
-               pl->u32FCRn_Save,pl->u32FSICn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRnValue: 0x%x u32FSICnValue: 0x%x\n",
-               pl->u32FCRnValue,pl->u32FSICnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRnAddress: 0x%x u32FSICnAddress: 0x%x\n",
-               pl->u32FCRnAddress,pl->u32FSICnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n",
-               pl->u32FPDRnValue,pl->u32FPDRnAddress));
-}
-static void printpipelines(struct cs4281_state *s)
-{
-       int i;
-       for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-       {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-                       printpipe(&s->pl[i]);
-               }
-       }
-}
-/****************************************************************************
-*
-*  Suspend - save the ac97 regs, mute the outputs and power down the part.  
-*
-****************************************************************************/
-static void cs4281_ac97_suspend(struct cs4281_state *s)
-{
-       int Count,i;
-
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()+\n"));
-/*
-* change the state, save the current hwptr, then stop the dac/adc
-*/
-       s->pm.flags &= ~CS4281_PM_IDLE;
-       s->pm.flags |= CS4281_PM_SUSPENDING;
-       s->pm.u32hwptr_playback = readl(s->pBA0 + BA0_DCA0);
-       s->pm.u32hwptr_capture = readl(s->pBA0 + BA0_DCA1);
-       stop_dac(s);
-       stop_adc(s);
-
-       for(Count = 0x2, i=0; (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-                       && (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-               Count += 2, i++)
-       {
-               cs4281_read_ac97(s, BA0_AC97_RESET + Count, &s->pm.ac97[i]);
-       }
-/*
-* Save the ac97 volume registers as well as the current powerdown state.
-* Now, mute the all the outputs (master, headphone, and mono), as well
-* as the PCM volume, in preparation for powering down the entire part.
-*/ 
-       cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME, &s->pm.u32AC97_master_volume);
-       cs4281_read_ac97(s, BA0_AC97_HEADPHONE_VOLUME, &s->pm.u32AC97_headphone_volume);
-       cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, &s->pm.u32AC97_master_volume_mono);
-       cs4281_read_ac97(s, BA0_AC97_PCM_OUT_VOLUME, &s->pm.u32AC97_pcm_out_volume);
-               
-       cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
-
-       cs4281_read_ac97(s, BA0_AC97_POWERDOWN, &s->pm.u32AC97_powerdown);
-       cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &s->pm.u32AC97_general_purpose);
-
-/*
-* And power down everything on the AC97 codec.
-*/
-       cs4281_write_ac97(s, BA0_AC97_POWERDOWN, 0xff00);
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()-\n"));
-}
-
-/****************************************************************************
-*
-*  Resume - power up the part and restore its registers..  
-*
-****************************************************************************/
-static void cs4281_ac97_resume(struct cs4281_state *s)
-{
-       int Count,i;
-
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()+\n"));
-
-/* do not save the power state registers at this time
-    //
-    // If we saved away the power control registers, write them into the
-    // shadows so those saved values get restored instead of the current
-    // shadowed value.
-    //
-    if( bPowerStateSaved )
-    {
-        PokeShadow( 0x26, ulSaveReg0x26 );
-        bPowerStateSaved = FALSE;
-    }
-*/
-
-//
-// First, we restore the state of the general purpose register.  This
-// contains the mic select (mic1 or mic2) and if we restore this after
-// we restore the mic volume/boost state and mic2 was selected at
-// suspend time, we will end up with a brief period of time where mic1
-// is selected with the volume/boost settings for mic2, causing
-// acoustic feedback.  So we restore the general purpose register
-// first, thereby getting the correct mic selected before we restore
-// the mic volume/boost.
-//
-       cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, s->pm.u32AC97_general_purpose);
-
-//
-// Now, while the outputs are still muted, restore the state of power
-// on the AC97 part.
-//
-       cs4281_write_ac97(s, BA0_AC97_POWERDOWN, s->pm.u32AC97_powerdown);
-
-/*
-* Restore just the first set of registers, from register number
-* 0x02 to the register number that ulHighestRegToRestore specifies.
-*/
-       for(    Count = 0x2, i=0; 
-               (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-                       && (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-               Count += 2, i++)
-       {
-               cs4281_write_ac97(s, BA0_AC97_RESET + Count, s->pm.ac97[i]);
-       }
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()-\n"));
-}
-
-/* do not save the power state registers at this time
-****************************************************************************
-*
-*  SavePowerState - Save the power registers away. 
-*
-****************************************************************************
-void 
-HWAC97codec::SavePowerState(void)
-{
-    ENTRY(TM_OBJECTCALLS, "HWAC97codec::SavePowerState()\r\n");
-
-    ulSaveReg0x26 = PeekShadow(0x26);
-
-    //
-    // Note that we have saved registers that need to be restored during a
-    // resume instead of ulAC97Regs[].
-    //
-    bPowerStateSaved = TRUE;
-
-} // SavePowerState
-*/
-
-static void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to save the contents of the BASIC FIFO Registers.
- */
-       pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress);
-       pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to restore the contents of the BASIC FIFO Registers.
- */
-       writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress);
-       writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-       //
-       // We need to save the contents of the BASIC DMA Registers.
-       //
-       pl->u32DBAn_Save = readl(s->pBA0 + pl->u32DBAnAddress);
-       pl->u32DBCn_Save = readl(s->pBA0 + pl->u32DBCnAddress);
-       pl->u32DMRn_Save = readl(s->pBA0 + pl->u32DMRnAddress);
-       pl->u32DCRn_Save = readl(s->pBA0 + pl->u32DCRnAddress);
-       pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress);
-       pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress);
-}
-static void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-       //
-       // We need to save the contents of the BASIC DMA Registers.
-       //
-       writel( pl->u32DBAn_Save, s->pBA0 + pl->u32DBAnAddress);
-       writel( pl->u32DBCn_Save, s->pBA0 + pl->u32DBCnAddress);
-       writel( pl->u32DMRn_Save, s->pBA0 + pl->u32DMRnAddress);
-       writel( pl->u32DCRn_Save, s->pBA0 + pl->u32DCRnAddress);
-       writel( pl->u32DCCn_Save, s->pBA0 + pl->u32DCCnAddress);
-       writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress);
-}
-
-static int cs4281_suspend(struct cs4281_state *s)
-{
-       int i;
-       u32 u32CLKCR1;
-       struct cs4281_pm *pm = &s->pm;
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-               printk("cs4281: cs4281_suspend()+ flags=%d\n",
-                       (unsigned)s->pm.flags));
-/*
-* check the current state, only suspend if IDLE
-*/
-       if(!(s->pm.flags & CS4281_PM_IDLE))
-       {
-               CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-                       printk("cs4281: cs4281_suspend() unable to suspend, not IDLE\n"));
-               return 1;
-       }
-       s->pm.flags &= ~CS4281_PM_IDLE;
-       s->pm.flags |= CS4281_PM_SUSPENDING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-
-       pm->u32CLKCR1_SAVE = u32CLKCR1;
-       if(!(u32CLKCR1 & 0x00010000 ) )
-               writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-//
-// First, turn on the clocks (yikes) to the devices, so that they will
-// respond when we try to save their state.
-//
-       if(!(u32CLKCR1 & CLKCR1_SWCE))
-       {
-               writel(u32CLKCR1 | CLKCR1_SWCE , s->pBA0 + BA0_CLKCR1);
-       }
-    
-       //
-       // Save the power state
-       //
-       pm->u32SSPMValue = readl(s->pBA0 + BA0_SSPM);
-
-       //
-       // Disable interrupts.
-       //
-       writel(HICR_CHGM, s->pBA0 + BA0_HICR);
-
-       //
-       // Save the PCM Playback Left and Right Volume Control.
-       //
-       pm->u32PPLVCvalue = readl(s->pBA0 + BA0_PPLVC);
-       pm->u32PPRVCvalue = readl(s->pBA0 + BA0_PPRVC);
-
-       //
-       // Save the FM Synthesis Left and Right Volume Control.
-       //
-       pm->u32FMLVCvalue = readl(s->pBA0 + BA0_FMLVC);
-       pm->u32FMRVCvalue = readl(s->pBA0 + BA0_FMRVC);
-
-       //
-       // Save the GPIOR value.
-       //
-       pm->u32GPIORvalue = readl(s->pBA0 + BA0_GPIOR);
-
-       //
-       // Save the JSCTL value.
-       //
-       pm->u32JSCTLvalue = readl(s->pBA0 + BA0_GPIOR);
-
-       //
-       // Save Sound System Control Register
-       //
-       pm->u32SSCR = readl(s->pBA0 + BA0_SSCR);
-
-       //
-       // Save SRC Slot Assinment register
-       //
-       pm->u32SRCSA = readl(s->pBA0 + BA0_SRCSA);
-
-       //
-       // Save sample rate
-       //
-       pm->u32DacASR = readl(s->pBA0 + BA0_PASR);
-       pm->u32AdcASR = readl(s->pBA0 + BA0_CASR);
-       pm->u32DacSR = readl(s->pBA0 + BA0_DACSR);
-       pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR);
-
-       //
-       // Loop through all of the PipeLines 
-       //
-       for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-               //
-               // Ask the DMAengines and FIFOs to Suspend.
-               //
-                       cs4281_SuspendDMAengine(s,&s->pl[i]);
-                       cs4281_SuspendFIFO(s,&s->pl[i]);
-               }
-       }
-       //
-       // We need to save the contents of the Midi Control Register.
-       //
-       pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR);
-/*
-* save off the AC97 part information
-*/
-       cs4281_ac97_suspend(s);
-    
-       //
-       // Turn off the serial ports.
-       //
-       writel(0, s->pBA0 + BA0_SERMC);
-
-       //
-       // Power off FM, Joystick, AC link, 
-       //
-       writel(0, s->pBA0 + BA0_SSPM);
-
-       //
-       // DLL off.
-       //
-       writel(0, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // AC link off.
-       //
-       writel(0, s->pBA0 + BA0_SPMC);
-
-       //
-       // Put the chip into D3(hot) state.
-       //
-       // PokeBA0(BA0_PMCS, 0x00000003);
-
-       //
-       // Gershwin CLKRUN - Clear CKRA
-       //
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-       writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1);
-
-#ifdef CSDEBUG
-       printpm(s);
-       printpipelines(s);
-#endif
-
-       s->pm.flags &= ~CS4281_PM_SUSPENDING;
-       s->pm.flags |= CS4281_PM_SUSPENDED;
-
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-               printk("cs4281: cs4281_suspend()- flags=%d\n",
-                       (unsigned)s->pm.flags));
-       return 0;
-}
-
-static int cs4281_resume(struct cs4281_state *s)
-{
-       int i;
-       unsigned temp1;
-       u32 u32CLKCR1;
-       struct cs4281_pm *pm = &s->pm;
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 4, 
-               printk( "cs4281: cs4281_resume()+ flags=%d\n",
-                       (unsigned)s->pm.flags));
-       if(!(s->pm.flags & CS4281_PM_SUSPENDED))
-       {
-               CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-                       printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n"));
-               return 1;
-       }
-       s->pm.flags &= ~CS4281_PM_SUSPENDED;
-       s->pm.flags |= CS4281_PM_RESUMING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-       writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // set the power state.
-       //
-       //old PokeBA0(BA0_PMCS, 0);
-
-       //
-       // Program the clock circuit and serial ports.
-       //
-       temp1 = cs4281_hw_init(s);
-       if (temp1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1,
-                   printk(KERN_ERR
-                       "cs4281: resume cs4281_hw_init() error.\n"));
-               return -1;
-       }
-
-       //
-       // restore the Power state
-       //
-       writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM);
-
-       //
-       // Set post SRC mix setting (FM or ALT48K)
-       //
-       writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM);
-
-       //
-       // Loop through all of the PipeLines 
-       //
-       for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-               //
-               // Ask the DMAengines and FIFOs to Resume.
-               //
-                       cs4281_ResumeDMAengine(s,&s->pl[i]);
-                       cs4281_ResumeFIFO(s,&s->pl[i]);
-               }
-       }
-       //
-       // We need to restore the contents of the Midi Control Register.
-       //
-       writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR);
-
-       cs4281_ac97_resume(s);
-       //
-       // Restore the PCM Playback Left and Right Volume Control.
-       //
-       writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC);
-       writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC);
-
-       //
-       // Restore the FM Synthesis Left and Right Volume Control.
-       //
-       writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC);
-       writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC);
-
-       //
-       // Restore the JSCTL value.
-       //
-       writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL);
-
-       //
-       // Restore the GPIOR register value.
-       //
-       writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR);
-
-       //
-       // Restore Sound System Control Register
-       //
-       writel(pm->u32SSCR, s->pBA0 + BA0_SSCR);
-
-       //
-       // Restore SRC Slot Assignment register
-       //
-       writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA);
-
-       //
-       // Restore sample rate
-       //
-       writel(pm->u32DacASR, s->pBA0 + BA0_PASR);
-       writel(pm->u32AdcASR, s->pBA0 + BA0_CASR);
-       writel(pm->u32DacSR, s->pBA0 + BA0_DACSR);
-       writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR);
-
-       // 
-       // Restore CFL1/2 registers we saved to compensate for OEM bugs.
-       //
-       //      PokeBA0(BA0_CFLR, ulConfig);
-
-       //
-       // Gershwin CLKRUN - Clear CKRA
-       //
-       writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // Enable interrupts on the part.
-       //
-       writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-
-#ifdef CSDEBUG
-       printpm(s);
-       printpipelines(s);
-#endif
-/*
-* change the state, restore the current hwptrs, then stop the dac/adc
-*/
-       s->pm.flags |= CS4281_PM_IDLE;
-       s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED 
-                       | CS4281_PM_RESUMING | CS4281_PM_RESUMED);
-
-       writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0);
-       writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1);
-       start_dac(s);
-       start_adc(s);
-
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n",
-               (unsigned)s->pm.flags));
-       return 0;
-}
-
-#endif
-
-//******************************************************************************
-// "cs4281_play_rate()" --
-//******************************************************************************
-static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
-{
-       u32 DACSRvalue = 1;
-
-       // Based on the sample rate, program the DACSR register.
-       if (playrate == 8000)
-               DACSRvalue = 5;
-       if (playrate == 11025)
-               DACSRvalue = 4;
-       else if (playrate == 22050)
-               DACSRvalue = 2;
-       else if (playrate == 44100)
-               DACSRvalue = 1;
-       else if ((playrate <= 48000) && (playrate >= 6023))
-               DACSRvalue = 24576000 / (playrate * 16);
-       else if (playrate < 6023)
-               // Not allowed by open.
-               return;
-       else if (playrate > 48000)
-               // Not allowed by open.
-               return;
-       CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
-               "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
-                       DACSRvalue, playrate));
-       //  Write the 'sample rate select code'
-       //  to the 'DAC Sample Rate' register.
-       writel(DACSRvalue, card->pBA0 + BA0_DACSR);     // (744h)
-}
-
-//******************************************************************************
-// "cs4281_record_rate()" -- Initialize the record sample rate converter.
-//******************************************************************************
-static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
-{
-       u32 ADCSRvalue = 1;
-
-       //
-       // Based on the sample rate, program the ADCSR register
-       //
-       if (outrate == 8000)
-               ADCSRvalue = 5;
-       if (outrate == 11025)
-               ADCSRvalue = 4;
-       else if (outrate == 22050)
-               ADCSRvalue = 2;
-       else if (outrate == 44100)
-               ADCSRvalue = 1;
-       else if ((outrate <= 48000) && (outrate >= 6023))
-               ADCSRvalue = 24576000 / (outrate * 16);
-       else if (outrate < 6023) {
-               // Not allowed by open.
-               return;
-       } else if (outrate > 48000) {
-               // Not allowed by open.
-               return;
-       }
-       CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
-               "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
-                       ADCSRvalue, outrate));
-       //  Write the 'sample rate select code
-       //  to the 'ADC Sample Rate' register.
-       writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);     // (748h)
-}
-
-
-
-static void stop_dac(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n"));
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_WRITE;
-       temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK;
-       writel(temp1, s->pBA0 + BA0_DCR0);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void start_dac(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n"));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
-                                       (s->dma_dac.count > 0
-                                       && s->dma_dac.ready))
-#ifndef NOT_CS4281_PM
-       && (s->pm.flags & CS4281_PM_IDLE))
-#else
-)
-#endif
- {
-               s->ena |= FMODE_WRITE;
-               temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK;  // Clear DMA0 channel mask.
-               writel(temp1, s->pBA0 + BA0_DCR0);      // Start DMA'ing.
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts.              
-
-               writel(7, s->pBA0 + BA0_PPRVC);
-               writel(7, s->pBA0 + BA0_PPLVC);
-               CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: start_dac(): writel 0x%x start dma\n", temp1));
-
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: start_dac()-\n"));
-}
-
-
-static void stop_adc(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: stop_adc()+\n"));
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_READ;
-
-       if (s->conversion == 1) {
-               s->conversion = 0;
-               s->prop_adc.fmt = s->prop_adc.fmt_original;
-       }
-       temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK;
-       writel(temp1, s->pBA0 + BA0_DCR1);
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: stop_adc()-\n"));
-}
-
-
-static void start_adc(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: start_adc()+\n"));
-
-       if (!(s->ena & FMODE_READ) &&
-           (s->dma_adc.mapped || s->dma_adc.count <=
-            (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize))
-           && s->dma_adc.ready
-#ifndef NOT_CS4281_PM
-       && (s->pm.flags & CS4281_PM_IDLE))
-#else
-) 
-#endif
-       {
-               if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
-                       // 
-                       // now only use 16 bit capture, due to truncation issue
-                       // in the chip, noticable distortion occurs.
-                       // allocate buffer and then convert from 16 bit to 
-                       // 8 bit for the user buffer.
-                       //
-                       s->prop_adc.fmt_original = s->prop_adc.fmt;
-                       if (s->prop_adc.fmt & AFMT_S8) {
-                               s->prop_adc.fmt &= ~AFMT_S8;
-                               s->prop_adc.fmt |= AFMT_S16_LE;
-                       }
-                       if (s->prop_adc.fmt & AFMT_U8) {
-                               s->prop_adc.fmt &= ~AFMT_U8;
-                               s->prop_adc.fmt |= AFMT_U16_LE;
-                       }
-                       //
-                       // prog_dmabuf_adc performs a stop_adc() but that is
-                       // ok since we really haven't started the DMA yet.
-                       //
-                       prog_codec(s, CS_TYPE_ADC);
-
-                       if (prog_dmabuf_adc(s) != 0) {
-                               CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-                                        "cs4281: start_adc(): error in prog_dmabuf_adc\n"));
-                       }
-                       s->conversion = 1;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               s->ena |= FMODE_READ;
-               temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK;  // Clear DMA1 channel mask bit.
-               writel(temp1, s->pBA0 + BA0_DCR1);      // Start recording
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts.
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
-                        "cs4281: start_adc(): writel 0x%x \n", temp1));
-       }
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: start_adc()-\n"));
-
-}
-
-
-// --------------------------------------------------------------------- 
-
-#define DMABUF_MINORDER 1      // ==> min buffer size = 8K.
-
-
-static void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-       struct page *map, *mapend;
-
-       if (db->rawbuf) {
-               // Undo prog_dmabuf()'s marking the pages as reserved 
-               mapend =
-                   virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
-                                1);
-               for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-                       ClearPageReserved(map);
-               free_dmabuf(s, db);
-       }
-       if (s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-               // Undo prog_dmabuf()'s marking the pages as reserved 
-               mapend =
-                   virt_to_page(s->tmpbuff +
-                                (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-               for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-                       ClearPageReserved(map);
-               free_dmabuf2(s, db);
-       }
-       s->tmpbuff = NULL;
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-       int order;
-       unsigned bytespersec, temp1;
-       unsigned bufs, sample_shift = 0;
-       struct page *map, *mapend;
-       unsigned long df;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_dmabuf()+\n"));
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
-           db->endcleared = db->blocks = db->wakeup = db->underrun = 0;
-/*
-* check for order within limits, but do not overwrite value, check
-* later for a fractional defaultorder (i.e. 100+).
-*/
-       if((defaultorder > 0) && (defaultorder < 12))
-               df = defaultorder;
-       else
-               df = 1; 
-
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = df; order >= DMABUF_MINORDER; order--)
-                       if ( (db->rawbuf = (void *) pci_alloc_consistent(
-                               s->pcidev, PAGE_SIZE << order, &db-> dmaaddr)))
-                                   break;
-               if (!db->rawbuf) {
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                               "cs4281: prog_dmabuf(): unable to allocate rawbuf\n"));
-                       return -ENOMEM;
-               }
-               db->buforder = order;
-               // Now mark the pages as reserved; otherwise the 
-               // remap_pfn_range() in cs4281_mmap doesn't work.
-               // 1. get index to last page in mem_map array for rawbuf.
-               mapend = virt_to_page(db->rawbuf + 
-                       (PAGE_SIZE << db->buforder) - 1);
-
-               // 2. mark each physical page in range as 'reserved'.
-               for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-                       SetPageReserved(map);
-       }
-       if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-               for (order = df; order >= DMABUF_MINORDER;
-                    order--)
-                       if ( (s->tmpbuff = (void *) pci_alloc_consistent(
-                                       s->pcidev, PAGE_SIZE << order, 
-                                       &s->dmaaddr_tmpbuff)))
-                                   break;
-               if (!s->tmpbuff) {
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                               "cs4281: prog_dmabuf(): unable to allocate tmpbuff\n"));
-                       return -ENOMEM;
-               }
-               s->buforder_tmpbuff = order;
-               // Now mark the pages as reserved; otherwise the 
-               // remap_pfn_range() in cs4281_mmap doesn't work.
-               // 1. get index to last page in mem_map array for rawbuf.
-               mapend = virt_to_page(s->tmpbuff + 
-                               (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-
-               // 2. mark each physical page in range as 'reserved'.
-               for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-                       SetPageReserved(map);
-       }
-       if (db->type == CS_TYPE_DAC) {
-               if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       sample_shift++;
-               if (s->prop_dac.channels > 1)
-                       sample_shift++;
-               bytespersec = s->prop_dac.rate << sample_shift;
-       } else                  // CS_TYPE_ADC
-       {
-               if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       sample_shift++;
-               if (s->prop_adc.channels > 1)
-                       sample_shift++;
-               bytespersec = s->prop_adc.rate << sample_shift;
-       }
-       bufs = PAGE_SIZE << db->buforder;
-
-/*
-* added fractional "defaultorder" inputs. if >100 then use 
-* defaultorder-100 as power of 2 for the buffer size. example:
-* 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*/
-       if(defaultorder >= 100)
-       {
-               bufs = 1 << (defaultorder-100);
-       }
-
-#define INTERRUPT_RATE_MS       100    // Interrupt rate in milliseconds.
-       db->numfrag = 2;
-/* 
-* Nominal frag size(bytes/interrupt)
-*/
-       temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS);
-       db->fragshift = 8;      // Min 256 bytes.
-       while (1 << db->fragshift < temp1)      // Calc power of 2 frag size.
-               db->fragshift += 1;
-       db->fragsize = 1 << db->fragshift;
-       db->dmasize = db->fragsize * 2;
-       db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment.
-
-// If the calculated size is larger than the allocated
-//  buffer, divide the allocated buffer into 2 fragments.
-       if (db->dmasize > bufs) {
-
-               db->numfrag = 2;        // Two fragments.
-               db->fragsize = bufs >> 1;       // Each 1/2 the alloc'ed buffer.
-               db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment.
-               db->dmasize = bufs;     // Use all the alloc'ed buffer.
-
-               db->fragshift = 0;      // Calculate 'fragshift'.
-               temp1 = db->fragsize;   // update_ptr() uses it 
-               while ((temp1 >>= 1) > 1)       // to calc 'total-bytes'
-                       db->fragshift += 1;     // returned in DSP_GETI/OPTR. 
-       }
-       CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n",
-                       db->numfrag, db->fragsize, db->fragsamples, 
-                       db->fragshift, bufs, 
-                       (db->type == CS_TYPE_DAC) ? s->prop_dac.fmt : 
-                               s->prop_adc.fmt, 
-                       (db->type == CS_TYPE_DAC) ? s->prop_dac.channels : 
-                               s->prop_adc.channels));
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_dmabuf()-\n"));
-       return 0;
-}
-
-
-static int prog_dmabuf_adc(struct cs4281_state *s)
-{
-       unsigned long va;
-       unsigned count;
-       int c;
-       stop_adc(s);
-       s->dma_adc.type = CS_TYPE_ADC;
-       if ((c = prog_dmabuf(s, &s->dma_adc)))
-               return c;
-
-       if (s->dma_adc.rawbuf) {
-               memset(s->dma_adc.rawbuf,
-                      (s->prop_adc.
-                       fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-                      s->dma_adc.dmasize);
-       }
-       if (s->tmpbuff) {
-               memset(s->tmpbuff,
-                      (s->prop_adc.
-                       fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-                      PAGE_SIZE << s->buforder_tmpbuff);
-       }
-
-       va = virt_to_bus(s->dma_adc.rawbuf);
-
-       count = s->dma_adc.dmasize;
-
-       if (s->prop_adc.
-           fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-                   count /= 2; // 16-bit.
-
-       if (s->prop_adc.channels > 1)
-               count /= 2;     // Assume stereo.
-
-       CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n",
-                       count, (unsigned) va));
-
-       writel(va, s->pBA0 + BA0_DBA1); // Set buffer start address.
-       writel(count - 1, s->pBA0 + BA0_DBC1);  // Set count. 
-       s->dma_adc.ready = 1;
-       return 0;
-}
-
-
-static int prog_dmabuf_dac(struct cs4281_state *s)
-{
-       unsigned long va;
-       unsigned count;
-       int c;
-       stop_dac(s);
-       s->dma_dac.type = CS_TYPE_DAC;
-       if ((c = prog_dmabuf(s, &s->dma_dac)))
-               return c;
-       memset(s->dma_dac.rawbuf,
-              (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-              s->dma_dac.dmasize);
-
-       va = virt_to_bus(s->dma_dac.rawbuf);
-
-       count = s->dma_dac.dmasize;
-       if (s->prop_dac.
-           fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-                   count /= 2; // 16-bit.
-
-       if (s->prop_dac.channels > 1)
-               count /= 2;     // Assume stereo.
-
-       writel(va, s->pBA0 + BA0_DBA0); // Set buffer start address.
-       writel(count - 1, s->pBA0 + BA0_DBC0);  // Set count.             
-
-       CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n",
-                       count, (unsigned) va));
-
-       s->dma_dac.ready = 1;
-       return 0;
-}
-
-
-static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
-                         unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *) buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
-               "cs4281: clear_advance(): memset %d at %p for %d size \n",
-                       (unsigned)c, ((char *) buf) + bptr, len));
-       memset(((char *) buf) + bptr, c, len);
-}
-
-
-
-// call with spinlock held! 
-static void cs4281_update_ptr(struct cs4281_state *s, int intflag)
-{
-       int diff;
-       unsigned hwptr, va;
-
-       // update ADC pointer 
-       if (s->ena & FMODE_READ) {
-               hwptr = readl(s->pBA0 + BA0_DCA1);      // Read capture DMA address.
-               va = virt_to_bus(s->dma_adc.rawbuf);
-               hwptr -= (unsigned) va;
-               diff =
-                   (s->dma_adc.dmasize + hwptr -
-                    s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count > s->dma_adc.dmasize)
-                       s->dma_adc.count = s->dma_adc.dmasize;
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >=
-                           (signed) s->dma_adc.fragsize) wake_up(&s->
-                                                                 dma_adc.
-                                                                 wait);
-               } else {
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
-               }
-               CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-                               s, s->dma_adc.hwptr, s->dma_adc.total_bytes, s->dma_adc.count));
-       }
-       // update DAC pointer 
-       //
-       // check for end of buffer, means that we are going to wait for another interrupt
-       // to allow silence to fill the fifos on the part, to keep pops down to a minimum.
-       //
-       if (s->ena & FMODE_WRITE) {
-               hwptr = readl(s->pBA0 + BA0_DCA0);      // Read play DMA address.
-               va = virt_to_bus(s->dma_dac.rawbuf);
-               hwptr -= (unsigned) va;
-               diff = (s->dma_dac.dmasize + hwptr -
-                    s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= s->dma_dac.fragsize) {
-                               s->dma_dac.wakeup = 1;
-                               wake_up(&s->dma_dac.wait);
-                               if (s->dma_dac.count > s->dma_dac.dmasize)
-                                       s->dma_dac.count &=
-                                           s->dma_dac.dmasize - 1;
-                       }
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               //
-                               // fill with silence, and do not shut down the DAC.
-                               // Continue to play silence until the _release.
-                               //
-                               CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
-                                       "cs4281: cs4281_update_ptr(): memset %d at %p for %d size \n",
-                                               (unsigned)(s->prop_dac.fmt & 
-                                               (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
-                                               s->dma_dac.rawbuf, s->dma_dac.dmasize));
-                               memset(s->dma_dac.rawbuf,
-                                      (s->prop_dac.
-                                       fmt & (AFMT_U8 | AFMT_U16_LE)) ?
-                                      0x80 : 0, s->dma_dac.dmasize);
-                               if (s->dma_dac.count < 0) {
-                                       s->dma_dac.underrun = 1;
-                                       s->dma_dac.count = 0;
-                                       CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
-                                        "cs4281: cs4281_update_ptr(): underrun\n"));
-                               }
-                       } else if (s->dma_dac.count <=
-                                  (signed) s->dma_dac.fragsize
-                                  && !s->dma_dac.endcleared) {
-                               clear_advance(s->dma_dac.rawbuf,
-                                             s->dma_dac.dmasize,
-                                             s->dma_dac.swptr,
-                                             s->dma_dac.fragsize,
-                                             (s->prop_dac.
-                                              fmt & (AFMT_U8 |
-                                                     AFMT_U16_LE)) ? 0x80
-                                             : 0);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if ( (s->dma_dac.count <= (signed) s->dma_dac.dmasize/2) ||
-                               intflag)
-                       {
-                               wake_up(&s->dma_dac.wait);
-                       }
-               }
-               CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-                               s, s->dma_dac.hwptr, s->dma_dac.total_bytes, s->dma_dac.count));
-       }
-}
-
-
-// --------------------------------------------------------------------- 
-
-static void prog_codec(struct cs4281_state *s, unsigned type)
-{
-       unsigned long flags;
-       unsigned temp1, format;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_codec()+ \n"));
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (type == CS_TYPE_ADC) {
-               temp1 = readl(s->pBA0 + BA0_DCR1);
-               writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1);   // Stop capture DMA, if active.
-
-               // program sampling rates  
-               // Note, for CS4281, capture & play rates can be set independently.
-               cs4281_record_rate(s, s->prop_adc.rate);
-
-               // program ADC parameters 
-               format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
-               if (s->prop_adc.
-                   fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {    // 16-bit
-                       if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE))      // Big-endian?
-                               format |= DMRn_BEND;
-                       if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-                               format |= DMRn_USIGN;   // Unsigned.      
-               } else
-                       format |= DMRn_SIZE8 | DMRn_USIGN;      // 8-bit, unsigned
-               if (s->prop_adc.channels < 2)
-                       format |= DMRn_MONO;
-
-               writel(format, s->pBA0 + BA0_DMR1);
-
-               CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-                       "cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n",
-                               (format & DMRn_SIZE8) ? "8" : "16",
-                               (format & DMRn_USIGN) ?  "Unsigned" : "Signed", 
-                               (format & DMRn_MONO) ? "Mono" : "Stereo", 
-                               s->prop_adc.rate, format));
-
-               s->ena &= ~FMODE_READ;  // not capturing data yet
-       }
-
-
-       if (type == CS_TYPE_DAC) {
-               temp1 = readl(s->pBA0 + BA0_DCR0);
-               writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0);   // Stop play DMA, if active.
-
-               // program sampling rates  
-               // Note, for CS4281, capture & play rates can be set independently.
-               cs4281_play_rate(s, s->prop_dac.rate);
-
-               // program DAC parameters 
-               format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
-               if (s->prop_dac.
-                   fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {    // 16-bit
-                       if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE))
-                               format |= DMRn_BEND;    // Big Endian.
-                       if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-                               format |= DMRn_USIGN;   // Unsigned.      
-               } else
-                       format |= DMRn_SIZE8 | DMRn_USIGN;      // 8-bit, unsigned
-
-               if (s->prop_dac.channels < 2)
-                       format |= DMRn_MONO;
-
-               writel(format, s->pBA0 + BA0_DMR0);
-
-
-               CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-                       "cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n",
-                               (format & DMRn_SIZE8) ? "8" : "16",
-                               (format & DMRn_USIGN) ?  "Unsigned" : "Signed",
-                               (format & DMRn_MONO) ? "Mono" : "Stereo", 
-                               s->prop_dac.rate, format));
-
-               s->ena &= ~FMODE_WRITE; // not capturing data yet
-
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_codec()- \n"));
-}
-
-
-static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
-                      unsigned long arg)
-{
-       // Index to mixer_src[] is value of AC97 Input Mux Select Reg.
-       // Value of array member is recording source Device ID Mask.
-       static const unsigned int mixer_src[8] = {
-               SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
-               SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
-       };
-       void __user *argp = (void __user *)arg;
-
-       // Index of mixtable1[] member is Device ID 
-       // and must be <= SOUND_MIXER_NRDEVICES.
-       // Value of array member is index into s->mix.vol[]
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM] = 1,  // voice 
-               [SOUND_MIXER_LINE1] = 2,        // AUX
-               [SOUND_MIXER_CD] = 3,   // CD 
-               [SOUND_MIXER_LINE] = 4, // Line 
-               [SOUND_MIXER_SYNTH] = 5,        // FM
-               [SOUND_MIXER_MIC] = 6,  // Mic 
-               [SOUND_MIXER_SPEAKER] = 7,      // Speaker 
-               [SOUND_MIXER_RECLEV] = 8,       // Recording level 
-               [SOUND_MIXER_VOLUME] = 9        // Master Volume 
-       };
-
-
-       static const unsigned mixreg[] = {
-               BA0_AC97_PCM_OUT_VOLUME,
-               BA0_AC97_AUX_VOLUME,
-               BA0_AC97_CD_VOLUME,
-               BA0_AC97_LINE_IN_VOLUME
-       };
-       unsigned char l, r, rl, rr, vidx;
-       unsigned char attentbl[11] =
-           { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
-       unsigned temp1;
-       int i, val;
-
-       VALIDATE_STATE(s);
-       CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-                "cs4281: mixer_ioctl(): s=%p cmd=0x%.8x\n", s, cmd));
-#if CSDEBUG
-       cs_printioctl(cmd);
-#endif
-#if CSDEBUG_INTERFACE
-
-       if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
-           (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
-           (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
-           (cmd == SOUND_MIXER_CS_SETDBGLEVEL) ||
-           (cmd == SOUND_MIXER_CS_APM))
-       {
-               switch (cmd) {
-
-               case SOUND_MIXER_CS_GETDBGMASK:
-                       return put_user(cs_debugmask,
-                                       (unsigned long __user *) argp);
-
-               case SOUND_MIXER_CS_GETDBGLEVEL:
-                       return put_user(cs_debuglevel,
-                                       (unsigned long __user *) argp);
-
-               case SOUND_MIXER_CS_SETDBGMASK:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       cs_debugmask = val;
-                       return 0;
-
-               case SOUND_MIXER_CS_SETDBGLEVEL:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       cs_debuglevel = val;
-                       return 0;
-#ifndef NOT_CS4281_PM
-               case SOUND_MIXER_CS_APM:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       if(val == CS_IOCTL_CMD_SUSPEND)
-                               cs4281_suspend(s);
-                       else if(val == CS_IOCTL_CMD_RESUME)
-                               cs4281_resume(s);
-                       else
-                       {
-                               CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                                   "cs4281: mixer_ioctl(): invalid APM cmd (%d)\n",
-                                       val));
-                       }
-                       return 0;
-#endif
-               default:
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                               "cs4281: mixer_ioctl(): ERROR unknown debug cmd\n"));
-                       return 0;
-               }
-       }
-#endif
-
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               // enable/disable/query mixer preamp 
-               if (get_user(val, (int __user *) argp))
-                       return -EFAULT;
-               if (val != -1) {
-                       cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-                       temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
-                       cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-               }
-               cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-               val = (temp1 & 0x40) ? 1 : 0;
-               return put_user(val, (int __user *) argp);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               // enable/disable/query spatializer 
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               if (val != -1) {
-                       temp1 = (val & 0x3f) >> 2;
-                       cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
-                       cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-                                        &temp1);
-                       cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-                                         temp1 | 0x2000);
-               }
-               cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
-               return put_user((temp1 << 2) | 3, (int __user *)argp);
-       }
-       if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strlcpy(info.id, "CS4281", sizeof(info.id));
-               strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strlcpy(info.id, "CS4281", sizeof(info.id));
-               strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int __user *) argp);
-
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-               return -EINVAL;
-
-       // If ioctl has only the SIOC_READ bit(bit 31)
-       // on, process the only-read commands. 
-       if (_SIOC_DIR(cmd) == _SIOC_READ) {
-               switch (_IOC_NR(cmd)) {
-               case SOUND_MIXER_RECSRC:        // Arg contains a bit for each recording source 
-                       cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
-                       return put_user(mixer_src[temp1&7], (int __user *)argp);
-
-               case SOUND_MIXER_DEVMASK:       // Arg contains a bit for each supported device 
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-                                       SOUND_MASK_CD | SOUND_MASK_LINE |
-                                       SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME |
-                                       SOUND_MASK_RECLEV |
-                                       SOUND_MASK_SPEAKER, (int __user *)argp);
-
-               case SOUND_MIXER_RECMASK:       // Arg contains a bit for each supported recording source 
-                       return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
-                                       SOUND_MASK_CD | SOUND_MASK_VOLUME |
-                                       SOUND_MASK_LINE1, (int __user *) argp);
-
-               case SOUND_MIXER_STEREODEVS:    // Mixer channels supporting stereo 
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-                                       SOUND_MASK_CD | SOUND_MASK_LINE |
-                                       SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME |
-                                       SOUND_MASK_RECLEV, (int __user *)argp);
-
-               case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int __user *)argp);
-
-               default:
-                       i = _IOC_NR(cmd);
-                       if (i >= SOUND_MIXER_NRDEVICES
-                           || !(vidx = mixtable1[i]))
-                               return -EINVAL;
-                       return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-               }
-       }
-       // If ioctl doesn't have both the SIOC_READ and 
-       // the SIOC_WRITE bit set, return invalid.
-       if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
-               return -EINVAL;
-
-       // Increment the count of volume writes.
-       s->mix.modcnt++;
-
-       // Isolate the command; it must be a write.
-       switch (_IOC_NR(cmd)) {
-
-       case SOUND_MIXER_RECSRC:        // Arg contains a bit for each recording source 
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               i = hweight32(val);     // i = # bits on in val.
-               if (i != 1)     // One & only 1 bit must be on.
-                       return 0;
-               for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
-                       if (val == mixer_src[i]) {
-                               temp1 = (i << 8) | i;
-                               cs4281_write_ac97(s,
-                                                 BA0_AC97_RECORD_SELECT,
-                                                 temp1);
-                               return 0;
-                       }
-               }
-               return 0;
-
-       case SOUND_MIXER_VOLUME:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;        // Max soundcard.h vol is 100.
-               if (l < 6) {
-                       rl = 63;
-                       l = 0;
-               } else
-                       rl = attentbl[(10 * l) / 100];  // Convert 0-100 vol to 63-0 atten.
-
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;        // Max right volume is 100, too
-               if (r < 6) {
-                       rr = 63;
-                       r = 0;
-               } else
-                       rr = attentbl[(10 * r) / 100];  // Convert volume to attenuation.
-
-               if ((rl > 60) && (rr > 60))     // If both l & r are 'low',          
-                       temp1 = 0x8000; //  turn on the mute bit.
-               else
-                       temp1 = 0;
-
-               temp1 |= (rl << 8) | rr;
-
-               cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
-               cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[8] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[8] = val;
-#endif
-               return put_user(s->mix.vol[8], (int __user *)argp);
-
-       case SOUND_MIXER_SPEAKER:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 3) {
-                       rl = 0;
-                       l = 0;
-               } else {
-                       rl = (l * 2 - 5) / 13;  // Convert 0-100 range to 0-15.
-                       l = (rl * 13 + 5) / 2;
-               }
-
-               if (rl < 3) {
-                       temp1 = 0x8000;
-                       rl = 0;
-               } else
-                       temp1 = 0;
-               rl = 15 - rl;   // Convert volume to attenuation.
-               temp1 |= rl << 1;
-               cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[6] = l << 8;
-#else
-               s->mix.vol[6] = val;
-#endif
-               return put_user(s->mix.vol[6], (int __user *)argp);
-
-       case SOUND_MIXER_RECLEV:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               rl = (l * 2 - 5) / 13;  // Convert 0-100 scale to 0-15.
-               rr = (r * 2 - 5) / 13;
-               if (rl < 3 && rr < 3)
-                       temp1 = 0x8000;
-               else
-                       temp1 = 0;
-
-               temp1 = temp1 | (rl << 8) | rr;
-               cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[7] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[7] = val;
-#endif
-               return put_user(s->mix.vol[7], (int __user *)argp);
-
-       case SOUND_MIXER_MIC:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 1) {
-                       l = 0;
-                       rl = 0;
-               } else {
-                       rl = ((unsigned) l * 5 - 4) / 16;       // Convert 0-100 range to 0-31.
-                       l = (rl * 16 + 4) / 5;
-               }
-               cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-               temp1 &= 0x40;  // Isolate 20db gain bit.
-               if (rl < 3) {
-                       temp1 |= 0x8000;
-                       rl = 0;
-               }
-               rl = 31 - rl;   // Convert volume to attenuation.
-               temp1 |= rl;
-               cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[5] = val << 8;
-#else
-               s->mix.vol[5] = val;
-#endif
-               return put_user(s->mix.vol[5], (int __user *)argp);
-
-
-       case SOUND_MIXER_SYNTH:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               rl = (l * 2 - 11) / 3;  // Convert 0-100 range to 0-63.
-               rr = (r * 2 - 11) / 3;
-               if (rl < 3)     // If l is low, turn on
-                       temp1 = 0x0080; //  the mute bit.
-               else
-                       temp1 = 0;
-
-               rl = 63 - rl;   // Convert vol to attenuation.
-               writel(temp1 | rl, s->pBA0 + BA0_FMLVC);
-               if (rr < 3)     //  If rr is low, turn on
-                       temp1 = 0x0080; //   the mute bit.
-               else
-                       temp1 = 0;
-               rr = 63 - rr;   // Convert vol to attenuation.
-               writel(temp1 | rr, s->pBA0 + BA0_FMRVC);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[4] = (r << 8) | l;
-#else
-               s->mix.vol[4] = val;
-#endif
-               return put_user(s->mix.vol[4], (int __user *)argp);
-
-
-       default:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                       "cs4281: mixer_ioctl(): default\n"));
-
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                       return -EINVAL;
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 1) {
-                       l = 0;
-                       rl = 31;
-               } else
-                       rl = (attentbl[(l * 10) / 100]) >> 1;
-
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               if (r < 1) {
-                       r = 0;
-                       rr = 31;
-               } else
-                       rr = (attentbl[(r * 10) / 100]) >> 1;
-               if ((rl > 30) && (rr > 30))
-                       temp1 = 0x8000;
-               else
-                       temp1 = 0;
-               temp1 = temp1 | (rl << 8) | rr;
-               cs4281_write_ac97(s, mixreg[vidx - 1], temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[vidx - 1] = val;
-#endif
-#ifndef NOT_CS4281_PM
-               CS_DBGOUT(CS_PM, 9, printk(KERN_INFO 
-                       "write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n", 
-                               vidx-1,temp1,s->mix.vol[vidx-1]));
-#endif
-               return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-       }
-}
-
-
-// --------------------------------------------------------------------- 
-
-static int cs4281_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_open_mixdev()+\n"));
-
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-               if(s->dev_mixer == minor)
-                       break;
-       }
-       if (!s)
-       {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
-                       printk(KERN_INFO "cs4281: cs4281_open_mixdev()- -ENODEV\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_open_mixdev()- 0\n"));
-
-       return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-
-static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
-                              unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct cs4281_state *) file->private_data, cmd,
-                          arg);
-}
-
-
-// ******************************************************************************************
-//   Mixer file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = cs4281_ioctl_mixdev,
-       .open    = cs4281_open_mixdev,
-       .release = cs4281_release_mixdev,
-};
-
-// --------------------------------------------------------------------- 
-
-
-static int drain_adc(struct cs4281_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-
-       if (s->dma_adc.mapped)
-               return 0;
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_adc.count;
-               CS_DBGOUT(CS_FUNCTION, 2,
-                         printk(KERN_INFO "cs4281: drain_adc() %d\n", count));
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0) {
-                       CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-                                "cs4281: drain_adc() count<0\n"));
-                       break;
-               }
-               if (signal_pending(current))
-                       break;
-               if (nonblock) {
-                       remove_wait_queue(&s->dma_adc.wait, &wait);
-                       current->state = TASK_RUNNING;
-                       return -EBUSY;
-               }
-               tmo =
-                   3 * HZ * (count +
-                             s->dma_adc.fragsize) / 2 / s->prop_adc.rate;
-               if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->prop_adc.channels > 1)
-                       tmo >>= 1;
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "cs4281: dma timed out??\n");
-       }
-       remove_wait_queue(&s->dma_adc.wait, &wait);
-       current->state = TASK_RUNNING;
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-static int drain_dac(struct cs4281_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-
-       if (s->dma_dac.mapped)
-               return 0;
-       add_wait_queue(&s->dma_dac.wait, &wait);
-       for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                       break;
-               if (nonblock) {
-                       remove_wait_queue(&s->dma_dac.wait, &wait);
-                       current->state = TASK_RUNNING;
-                       return -EBUSY;
-               }
-               tmo =
-                   3 * HZ * (count +
-                             s->dma_dac.fragsize) / 2 / s->prop_dac.rate;
-               if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->prop_dac.channels > 1)
-                       tmo >>= 1;
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "cs4281: dma timed out??\n");
-       }
-       remove_wait_queue(&s->dma_dac.wait, &wait);
-       current->state = TASK_RUNNING;
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-//****************************************************************************
-//
-// CopySamples copies 16-bit stereo samples from the source to the
-// destination, possibly converting down to either 8-bit or mono or both.
-// count specifies the number of output bytes to write.
-//
-//  Arguments:
-//
-//  dst             - Pointer to a destination buffer.
-//  src             - Pointer to a source buffer
-//  count           - The number of bytes to copy into the destination buffer.
-//  iChannels       - Stereo - 2
-//                    Mono   - 1
-//  fmt             - AFMT_xxx (soundcard.h formats)
-//
-// NOTES: only call this routine for conversion to 8bit from 16bit
-//
-//****************************************************************************
-static void CopySamples(char *dst, char *src, int count, int iChannels,
-                       unsigned fmt)
-{
-
-       unsigned short *psSrc;
-       long lAudioSample;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: CopySamples()+ "));
-       CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                " dst=%p src=%p count=%d iChannels=%d fmt=0x%x\n",
-                        dst, src, (unsigned) count, (unsigned) iChannels, (unsigned) fmt));
-
-       // Gershwin does format conversion in hardware so normally
-       // we don't do any host based coversion. The data formatter
-       // truncates 16 bit data to 8 bit and that causes some hiss.
-       // We have already forced the HW to do 16 bit sampling and 
-       // 2 channel so that we can use software to round instead 
-       // of truncate
-
-       //
-       // See if the data should be output as 8-bit unsigned stereo.
-       // or if the data should be output at 8-bit unsigned mono.
-       //
-       if ( ((iChannels == 2) && (fmt & AFMT_U8)) ||
-               ((iChannels == 1) && (fmt & AFMT_U8)) ) {
-               //
-               // Convert each 16-bit unsigned stereo sample to 8-bit unsigned 
-               // stereo using rounding.
-               //
-               psSrc = (unsigned short *) src;
-               count = count / 2;
-               while (count--) {
-                       lAudioSample = (long) psSrc[count] + (long) 0x80;
-                       if (lAudioSample > 0xffff) {
-                               lAudioSample = 0xffff;
-                       }
-                       dst[count] = (char) (lAudioSample >> 8);
-               }
-       }
-       //
-       // check for 8-bit signed stereo.
-       //
-       else if ((iChannels == 2) && (fmt & AFMT_S8)) {
-               //
-               // Convert each 16-bit stereo sample to 8-bit stereo using rounding.
-               //
-               psSrc = (short *) src;
-               while (count--) {
-                       lAudioSample =
-                           (((long) psSrc[0] + (long) psSrc[1]) / 2);
-                       psSrc += 2;
-                       *dst++ = (char) ((short) lAudioSample >> 8);
-               }
-       }
-       //
-       // Otherwise, the data should be output as 8-bit signed mono.
-       //
-       else if ((iChannels == 1) && (fmt & AFMT_S8)) {
-               //
-               // Convert each 16-bit signed mono sample to 8-bit signed mono 
-               // using rounding.
-               //
-               psSrc = (short *) src;
-               count = count / 2;
-               while (count--) {
-                       lAudioSample =
-                           (((long) psSrc[0] + (long) psSrc[1]) / 2);
-                       if (lAudioSample > 0x7fff) {
-                               lAudioSample = 0x7fff;
-                       }
-                       psSrc += 2;
-                       *dst++ = (char) ((short) lAudioSample >> 8);
-               }
-       }
-}
-
-//
-// cs_copy_to_user()
-// replacement for the standard copy_to_user, to allow for a conversion from
-// 16 bit to 8 bit if the record conversion is active.  the cs4281 has some
-// issues with 8 bit capture, so the driver always captures data in 16 bit
-// and then if the user requested 8 bit, converts from 16 to 8 bit.
-//
-static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest,
-                               unsigned *hwsrc, unsigned cnt,
-                               unsigned *copied)
-{
-       void *src = hwsrc;      //default to the standard destination buffer addr
-
-       CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
-               "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=%p\n",
-                       s->prop_adc.fmt, s->prop_adc.fmt_original,
-                       (unsigned) cnt, dest));
-
-       if (cnt > s->dma_adc.dmasize) {
-               cnt = s->dma_adc.dmasize;
-       }
-       if (!cnt) {
-               *copied = 0;
-               return 0;
-       }
-       if (s->conversion) {
-               if (!s->tmpbuff) {
-                       *copied = cnt / 2;
-                       return 0;
-               }
-               CopySamples(s->tmpbuff, (void *) hwsrc, cnt,
-                           (unsigned) s->prop_adc.channels,
-                           s->prop_adc.fmt_original);
-               src = s->tmpbuff;
-               cnt = cnt / 2;
-       }
-
-       if (copy_to_user(dest, src, cnt)) {
-               *copied = 0;
-               return -EFAULT;
-       }
-       *copied = cnt;
-       CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-               "cs4281: cs_copy_to_user()- copied bytes is %d \n", cnt));
-       return 0;
-}
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count,
-                          loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       unsigned copied = 0;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-                 printk(KERN_INFO "cs4281: cs4281_read()+ %Zu \n", count));
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-//
-// "count" is the amount of bytes to read (from app), is decremented each loop
-//      by the amount of bytes that have been returned to the user buffer.
-// "cnt" is the running total of each read from the buffer (changes each loop)
-// "buffer" points to the app's buffer
-// "ret" keeps a running total of the amount of bytes that have been copied
-//      to the user buffer.
-// "copied" is the total bytes copied into the user buffer for each loop.
-//
-       while (count > 0) {
-               CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                       "_read() count>0 count=%Zu .count=%d .swptr=%d .hwptr=%d \n",
-                               count, s->dma_adc.count,
-                               s->dma_adc.swptr, s->dma_adc.hwptr));
-               spin_lock_irqsave(&s->lock, flags);
-
-               // get the current copy point of the sw buffer
-               swptr = s->dma_adc.swptr;
-
-               // cnt is the amount of unread bytes from the end of the 
-               // hw buffer to the current sw pointer
-               cnt = s->dma_adc.dmasize - swptr;
-
-               // dma_adc.count is the current total bytes that have not been read.
-               // if the amount of unread bytes from the current sw pointer to the
-               // end of the buffer is greater than the current total bytes that
-               // have not been read, then set the "cnt" (unread bytes) to the
-               // amount of unread bytes.  
-
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               //
-               // if we are converting from 8/16 then we need to copy
-               // twice the number of 16 bit bytes then 8 bit bytes.
-               // 
-               if (s->conversion) {
-                       if (cnt > (count * 2))
-                               cnt = (count * 2);
-               } else {
-                       if (cnt > count)
-                               cnt = count;
-               }
-               //
-               // "cnt" NOW is the smaller of the amount that will be read,
-               // and the amount that is requested in this read (or partial).
-               // if there are no bytes in the buffer to read, then start the
-               // ADC and wait for the interrupt handler to wake us up.
-               //
-               if (cnt <= 0) {
-
-                       // start up the dma engine and then continue back to the top of
-                       // the loop when wake up occurs.
-                       start_adc(s);
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->dma_adc.wait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               // there are bytes in the buffer to read.
-               // copy from the hw buffer over to the user buffer.
-               // user buffer is designated by "buffer"
-               // virtual address to copy from is rawbuf+swptr
-               // the "cnt" is the number of bytes to read.
-
-               CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
-                       "_read() copy_to cnt=%d count=%Zu ", cnt, count));
-               CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                        " .dmasize=%d .count=%d buffer=%p ret=%Zd\n",
-                                s->dma_adc.dmasize, s->dma_adc.count, buffer, ret));
-
-               if (cs_copy_to_user
-                   (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
-                       return ret ? ret : -EFAULT;
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= copied;
-               buffer += copied;
-               ret += copied;
-               start_adc(s);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-                 printk(KERN_INFO "cs4281: cs4281_read()- %Zd\n", ret));
-       return ret;
-}
-
-
-static ssize_t cs4281_write(struct file *file, const char __user *buffer,
-                           size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr, hwptr, busaddr;
-       int cnt;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-                 printk(KERN_INFO "cs4281: cs4281_write()+ count=%Zu\n",
-                        count));
-       VALIDATE_STATE(s);
-
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               if (s->dma_dac.underrun) {
-                       s->dma_dac.underrun = 0;
-                       hwptr = readl(s->pBA0 + BA0_DCA0);
-                       busaddr = virt_to_bus(s->dma_dac.rawbuf);
-                       hwptr -= (unsigned) busaddr;
-                       s->dma_dac.swptr = s->dma_dac.hwptr = hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize - swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       start_dac(s);
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->dma_dac.wait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
-                       return ret ? ret : -EFAULT;
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_dac(s);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-                 printk(KERN_INFO "cs4281: cs4281_write()- %Zd\n", ret));
-       return ret;
-}
-
-
-static unsigned int cs4281_poll(struct file *file,
-                               struct poll_table_struct *wait)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                 printk(KERN_INFO "cs4281: cs4281_poll()+\n"));
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                         printk(KERN_INFO
-                                "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                         printk(KERN_INFO
-                                "cs4281: cs4281_poll() wait on FMODE_READ\n"));
-               if(!s->dma_dac.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       cs4281_update_ptr(s,CS_FALSE);
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >=
-                           (signed) s->dma_dac.fragsize) {
-                               if (s->dma_dac.wakeup)
-                                       mask |= POLLOUT | POLLWRNORM;
-                               else
-                                       mask = 0;
-                               s->dma_dac.wakeup = 0;
-                       }
-               } else {
-                       if ((signed) (s->dma_dac.dmasize/2) >= s->dma_dac.count)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       } else if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) 
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                 printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",
-                        mask));
-       return mask;
-}
-
-
-static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       struct dmabuf *db;
-       int ret;
-       unsigned long size;
-
-       CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
-
-       VALIDATE_STATE(s);
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)) != 0)
-                       return ret;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0)
-                       return ret;
-               db = &s->dma_adc;
-       } else
-               return -EINVAL;
-//
-// only support PLAYBACK for now
-//
-       db = &s->dma_dac;
-
-       if (cs4x_pgoff(vma) != 0)
-               return -EINVAL;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               return -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               return -EAGAIN;
-       db->mapped = 1;
-
-       CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
-                        (unsigned) size));
-
-       return 0;
-}
-
-
-static int cs4281_ioctl(struct inode *inode, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       int val, mapped, ret;
-       int __user *p = (int __user *)arg;
-
-       CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-                "cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd));
-#if CSDEBUG
-       cs_printioctl(cmd);
-#endif
-       VALIDATE_STATE(s);
-       mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-           ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
-                                SOUND_VERSION));
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SYNC\n"));
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s,
-                                        0 /*file->f_flags & O_NONBLOCK */
-                                        );
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-                               DSP_CAP_TRIGGER | DSP_CAP_MMAP,
-                               p);
-
-       case SNDCTL_DSP_RESET:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_RESET\n"));
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr =
-                           s->dma_dac.count = s->dma_dac.total_bytes =
-                           s->dma_dac.blocks = s->dma_dac.wakeup = 0;
-                       prog_codec(s, CS_TYPE_DAC);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr =
-                           s->dma_adc.count = s->dma_adc.total_bytes =
-                           s->dma_adc.blocks = s->dma_dac.wakeup = 0;
-                       prog_codec(s, CS_TYPE_ADC);
-               }
-               return 0;
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val));
-               //
-               // support independent capture and playback channels
-               // assume that the file mode bit determines the 
-               // direction of the data flow.
-               //
-               if (file->f_mode & FMODE_READ) {
-                       if (val >= 0) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               // program sampling rates 
-                               if (val > 48000)
-                                       val = 48000;
-                               if (val < 6300)
-                                       val = 6300;
-                               s->prop_adc.rate = val;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val >= 0) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               // program sampling rates 
-                               if (val > 48000)
-                                       val = 48000;
-                               if (val < 6300)
-                                       val = 6300;
-                               s->prop_dac.rate = val;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               }
-
-               if (file->f_mode & FMODE_WRITE)
-                       val = s->prop_dac.rate;
-               else if (file->f_mode & FMODE_READ)
-                       val = s->prop_adc.rate;
-
-               return put_user(val, p);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val));
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       s->prop_adc.channels = val ? 2 : 1;
-                       prog_codec(s, CS_TYPE_ADC);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       s->prop_dac.channels = val ? 2 : 1;
-                       prog_codec(s, CS_TYPE_DAC);
-               }
-               return 0;
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
-                                val));
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       s->prop_adc.channels = 2;
-                               else
-                                       s->prop_adc.channels = 1;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       s->prop_dac.channels = 2;
-                               else
-                                       s->prop_dac.channels = 1;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               }
-
-               if (file->f_mode & FMODE_WRITE)
-                       val = s->prop_dac.channels;
-               else if (file->f_mode & FMODE_READ)
-                       val = s->prop_adc.channels;
-
-               return put_user(val, p);
-
-       case SNDCTL_DSP_GETFMTS:        // Returns a mask 
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n",
-                                AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-                                AFMT_U8));
-               return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-                               AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
-                                val));
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val != AFMT_S16_LE
-                                   && val != AFMT_U16_LE && val != AFMT_S8
-                                   && val != AFMT_U8)
-                                       val = AFMT_U8;
-                               s->prop_adc.fmt = val;
-                               s->prop_adc.fmt_original = s->prop_adc.fmt;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val != AFMT_S16_LE
-                                   && val != AFMT_U16_LE && val != AFMT_S8
-                                   && val != AFMT_U8)
-                                       val = AFMT_U8;
-                               s->prop_dac.fmt = val;
-                               s->prop_dac.fmt_original = s->prop_dac.fmt;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               } else {
-                       if (file->f_mode & FMODE_WRITE)
-                               val = s->prop_dac.fmt_original;
-                       else if (file->f_mode & FMODE_READ)
-                               val = s->prop_adc.fmt_original;
-               }
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                 "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n", 
-                       val));
-               return put_user(val, p);
-
-       case SNDCTL_DSP_POST:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_POST\n"));
-               return 0;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & s->ena & FMODE_READ)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & s->ena & FMODE_WRITE)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready
-                                   && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready
-                                   && (ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                               start_dac(s);
-                       } else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               if (s->dma_dac.mapped)
-                       abinfo.bytes = s->dma_dac.dmasize;
-               else
-                       abinfo.bytes =
-                           s->dma_dac.dmasize - s->dma_dac.count;
-               abinfo.fragstotal = s->dma_dac.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-               CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
-                               abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
-                               abinfo.fragments));
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(p, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               if (s->conversion) {
-                       abinfo.fragsize = s->dma_adc.fragsize / 2;
-                       abinfo.bytes = s->dma_adc.count / 2;
-                       abinfo.fragstotal = s->dma_adc.numfrag;
-                       abinfo.fragments =
-                           abinfo.bytes >> (s->dma_adc.fragshift - 1);
-               } else {
-                       abinfo.fragsize = s->dma_adc.fragsize;
-                       abinfo.bytes = s->dma_adc.count;
-                       abinfo.fragstotal = s->dma_adc.numfrag;
-                       abinfo.fragments =
-                           abinfo.bytes >> s->dma_adc.fragshift;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(p, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if(!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               cinfo.bytes = s->dma_adc.total_bytes;
-               if (s->dma_adc.mapped) {
-                       cinfo.blocks =
-                           (cinfo.bytes >> s->dma_adc.fragshift) -
-                           s->dma_adc.blocks;
-                       s->dma_adc.blocks =
-                           cinfo.bytes >> s->dma_adc.fragshift;
-               } else {
-                       if (s->conversion) {
-                               cinfo.blocks =
-                                   s->dma_adc.count /
-                                   2 >> (s->dma_adc.fragshift - 1);
-                       } else
-                               cinfo.blocks =
-                                   s->dma_adc.count >> s->dma_adc.
-                                   fragshift;
-               }
-               if (s->conversion)
-                       cinfo.ptr = s->dma_adc.hwptr / 2;
-               else
-                       cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize - 1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               cinfo.bytes = s->dma_dac.total_bytes;
-               if (s->dma_dac.mapped) {
-                       cinfo.blocks =
-                           (cinfo.bytes >> s->dma_dac.fragshift) -
-                           s->dma_dac.blocks;
-                       s->dma_dac.blocks =
-                           cinfo.bytes >> s->dma_dac.fragshift;
-               } else {
-                       cinfo.blocks =
-                           s->dma_dac.count >> s->dma_dac.fragshift;
-               }
-               cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize - 1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac(s)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               if (s->conversion)
-                       return put_user(s->dma_adc.fragsize / 2, p);
-               else
-                       return put_user(s->dma_adc.fragsize, p);
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               return 0;       // Say OK, but do nothing.
-
-       case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
-                   || (file->f_mode & FMODE_WRITE
-                       && s->dma_dac.subdivision)) return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               else if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-       case SOUND_PCM_READ_RATE:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->prop_adc.rate, p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->prop_adc.channels, p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.channels, p);
-
-       case SOUND_PCM_READ_BITS:
-               if (file->f_mode & FMODE_READ)
-                       return
-                           put_user(
-                                    (s->prop_adc.
-                                     fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return
-                           put_user(
-                                    (s->prop_dac.
-                                     fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    p);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-
-static int cs4281_release(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-
-       CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
-                "cs4281: cs4281_release(): inode=%p file=%p f_mode=%d\n",
-                        inode, file, file->f_mode));
-
-       VALIDATE_STATE(s);
-
-       if (file->f_mode & FMODE_WRITE) {
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-               mutex_lock(&s->open_sem_dac);
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-               s->open_mode &= ~FMODE_WRITE;
-               mutex_unlock(&s->open_sem_dac);
-               wake_up(&s->open_wait_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               drain_adc(s, file->f_flags & O_NONBLOCK);
-               mutex_lock(&s->open_sem_adc);
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-               s->open_mode &= ~FMODE_READ;
-               mutex_unlock(&s->open_sem_adc);
-               wake_up(&s->open_wait_adc);
-       }
-       return 0;
-}
-
-static int cs4281_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-               "cs4281: cs4281_open(): inode=%p file=%p f_mode=0x%x\n",
-                       inode, file, file->f_mode));
-
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-       if (entry == &cs4281_devs)
-               return -ENODEV;
-       if (!s) {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-                       "cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-
-       // wait for device to become free 
-       if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
-                        "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n"));
-               return -ENODEV;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               mutex_lock(&s->open_sem_dac);
-               while (s->open_mode & FMODE_WRITE) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               mutex_unlock(&s->open_sem_dac);
-                               return -EBUSY;
-                       }
-                       mutex_unlock(&s->open_sem_dac);
-                       interruptible_sleep_on(&s->open_wait_dac);
-
-                       if (signal_pending(current))
-                               return -ERESTARTSYS;
-                       mutex_lock(&s->open_sem_dac);
-               }
-       }
-       if (file->f_mode & FMODE_READ) {
-               mutex_lock(&s->open_sem_adc);
-               while (s->open_mode & FMODE_READ) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               mutex_unlock(&s->open_sem_adc);
-                               return -EBUSY;
-                       }
-                       mutex_unlock(&s->open_sem_adc);
-                       interruptible_sleep_on(&s->open_wait_adc);
-
-                       if (signal_pending(current))
-                               return -ERESTARTSYS;
-                       mutex_lock(&s->open_sem_adc);
-               }
-       }
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       if (file->f_mode & FMODE_READ) {
-               s->prop_adc.fmt = AFMT_U8;
-               s->prop_adc.fmt_original = s->prop_adc.fmt;
-               s->prop_adc.channels = 1;
-               s->prop_adc.rate = 8000;
-               s->prop_adc.clkdiv = 96 | 0x80;
-               s->conversion = 0;
-               s->ena &= ~FMODE_READ;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-                   s->dma_adc.subdivision = 0;
-               mutex_unlock(&s->open_sem_adc);
-
-               if (prog_dmabuf_adc(s)) {
-                       CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-                               "cs4281: adc Program dmabufs failed.\n"));
-                       cs4281_release(inode, file);
-                       return -ENOMEM;
-               }
-               prog_codec(s, CS_TYPE_ADC);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->prop_dac.fmt = AFMT_U8;
-               s->prop_dac.fmt_original = s->prop_dac.fmt;
-               s->prop_dac.channels = 1;
-               s->prop_dac.rate = 8000;
-               s->prop_dac.clkdiv = 96 | 0x80;
-               s->conversion = 0;
-               s->ena &= ~FMODE_WRITE;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-                   s->dma_dac.subdivision = 0;
-               mutex_unlock(&s->open_sem_dac);
-
-               if (prog_dmabuf_dac(s)) {
-                       CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-                               "cs4281: dac Program dmabufs failed.\n"));
-                       cs4281_release(inode, file);
-                       return -ENOMEM;
-               }
-               prog_codec(s, CS_TYPE_DAC);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
-                 printk(KERN_INFO "cs4281: cs4281_open()- 0\n"));
-       return nonseekable_open(inode, file);
-}
-
-
-// ******************************************************************************************
-//   Wave (audio) file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cs4281_read,
-       .write   = cs4281_write,
-       .poll    = cs4281_poll,
-       .ioctl   = cs4281_ioctl,
-       .mmap    = cs4281_mmap,
-       .open    = cs4281_open,
-       .release = cs4281_release,
-};
-
-// --------------------------------------------------------------------- 
-
-// hold spinlock for the following! 
-static void cs4281_handle_midi(struct cs4281_state *s)
-{
-       unsigned char ch;
-       int wake;
-       unsigned temp1;
-
-       wake = 0;
-       while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) {
-               ch = readl(s->pBA0 + BA0_MIDRP);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
-               temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff;
-               writel(temp1, s->pBA0 + BA0_MIDWP);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF - 16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-
-
-static irqreturn_t cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct cs4281_state *s = (struct cs4281_state *) dev_id;
-       unsigned int temp1;
-
-       // fastpath out, to ease interrupt sharing 
-       temp1 = readl(s->pBA0 + BA0_HISR);      // Get Int Status reg.
-
-       CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
-                 "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n", temp1));
-/*
-* If not DMA or MIDI interrupt, then just return.
-*/
-       if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-               CS_DBGOUT(CS_INTERRUPT, 9, printk(KERN_INFO
-                       "cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n"));
-               return IRQ_NONE;
-       }
-
-       if (temp1 & HISR_DMA0)  // If play interrupt,
-               readl(s->pBA0 + BA0_HDSR0);     //   clear the source.
-
-       if (temp1 & HISR_DMA1)  // Same for play.
-               readl(s->pBA0 + BA0_HDSR1);
-       writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Local EOI
-
-       spin_lock(&s->lock);
-       cs4281_update_ptr(s,CS_TRUE);
-       cs4281_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-// **************************************************************************
-
-static void cs4281_midi_timer(unsigned long data)
-{
-       struct cs4281_state *s = (struct cs4281_state *) data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       cs4281_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies + 1;
-       add_timer(&s->midi.timer);
-}
-
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_midi_read(struct file *file, char __user *buffer,
-                               size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->midi.iwait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
-                       return ret ? ret : -EFAULT;
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-       return ret;
-}
-
-
-static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer,
-                                size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0)
-                       cs4281_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->midi.owait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
-                       return ret ? ret : -EFAULT;
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       return ret;
-}
-
-
-static unsigned int cs4281_midi_poll(struct file *file,
-                                    struct poll_table_struct *wait)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_flags & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-
-static int cs4281_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned long flags, temp1;
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-
-               if (s->dev_midi == minor)
-                       break;
-       }
-
-       if (entry == &cs4281_devs)
-               return -ENODEV;
-       if (!s)
-       {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-                       "cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-       // wait for device to become free 
-       mutex_lock(&s->open_sem);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_sem);
-                       return -EBUSY;
-               }
-               mutex_unlock(&s->open_sem);
-               interruptible_sleep_on(&s->open_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_sem);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               writel(1, s->pBA0 + BA0_MIDCR); // Reset the interface.
-               writel(0, s->pBA0 + BA0_MIDCR); // Return to normal mode.
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               writel(0x0000000f, s->pBA0 + BA0_MIDCR);        // Enable transmit, record, ints.
-               temp1 = readl(s->pBA0 + BA0_HIMR);
-               writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR); // Enable midi int. recognition.
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies + 1;
-               s->midi.timer.data = (unsigned long) s;
-               s->midi.timer.function = cs4281_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |=
-           (file->
-            f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
-                                           FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_sem);
-       return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_midi_release(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               remove_wait_queue(&s->midi.owait, &wait);
-                               current->state = TASK_RUNNING;
-                               return -EBUSY;
-                       }
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG
-                                      "cs4281: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               current->state = TASK_RUNNING;
-       }
-       mutex_lock(&s->open_sem);
-       s->open_mode &=
-           (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
-                                                    FMODE_MIDI_WRITE);
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               writel(0, s->pBA0 + BA0_MIDCR); // Disable Midi interrupts.  
-               del_timer(&s->midi.timer);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       mutex_unlock(&s->open_sem);
-       wake_up(&s->open_wait);
-       return 0;
-}
-
-// ******************************************************************************************
-//   Midi file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_midi_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cs4281_midi_read,
-       .write   = cs4281_midi_write,
-       .poll    = cs4281_midi_poll,
-       .open    = cs4281_midi_open,
-       .release = cs4281_midi_release,
-};
-
-
-// --------------------------------------------------------------------- 
-
-// maximum number of devices 
-#define NR_DEVICE 8            // Only eight devices supported currently.
-
-// --------------------------------------------------------------------- 
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-
-       {
-       SOUND_MIXER_WRITE_VOLUME, 0x4040}, {
-       SOUND_MIXER_WRITE_PCM, 0x4040}, {
-       SOUND_MIXER_WRITE_SYNTH, 0x4040}, {
-       SOUND_MIXER_WRITE_CD, 0x4040}, {
-       SOUND_MIXER_WRITE_LINE, 0x4040}, {
-       SOUND_MIXER_WRITE_LINE1, 0x4040}, {
-       SOUND_MIXER_WRITE_RECLEV, 0x0000}, {
-       SOUND_MIXER_WRITE_SPEAKER, 0x4040}, {
-       SOUND_MIXER_WRITE_MIC, 0x0000}
-};
-
-
-#ifndef NOT_CS4281_PM
-static void __devinit cs4281_BuildFIFO(
-       struct cs4281_pipeline *p, 
-       struct cs4281_state *s)
-{
-       switch(p->number)
-       {
-               case 0:  /* playback */
-               {
-                       p->u32FCRnAddress  =  BA0_FCR0;
-                       p->u32FSICnAddress = BA0_FSIC0;
-                       p->u32FPDRnAddress = BA0_FPDR0;
-                       break;
-               }
-               case 1:  /* capture */
-               {
-                       p->u32FCRnAddress  =  BA0_FCR1;
-                       p->u32FSICnAddress = BA0_FSIC1;
-                       p->u32FPDRnAddress = BA0_FPDR1;
-                       break;
-               }
-
-               case 2: 
-               {
-                       p->u32FCRnAddress  =  BA0_FCR2;
-                       p->u32FSICnAddress = BA0_FSIC2;
-                       p->u32FPDRnAddress = BA0_FPDR2;
-                       break;
-               }
-               case 3: 
-               {
-                       p->u32FCRnAddress  =  BA0_FCR3;
-                       p->u32FSICnAddress = BA0_FSIC3;
-                       p->u32FPDRnAddress = BA0_FPDR3;
-                       break;
-               }
-               default:
-                       break;
-       }
-       //
-       // first read the hardware to initialize the member variables
-       //
-       p->u32FCRnValue = readl(s->pBA0 + p->u32FCRnAddress);
-       p->u32FSICnValue = readl(s->pBA0 + p->u32FSICnAddress);
-       p->u32FPDRnValue = readl(s->pBA0 + p->u32FPDRnAddress);
-
-}
-
-static void __devinit cs4281_BuildDMAengine(
-       struct cs4281_pipeline *p, 
-       struct cs4281_state *s)
-{
-/*
-* initialize all the addresses of this pipeline dma info.
-*/
-       switch(p->number)
-       {
-               case 0:  /* playback */
-               {
-                       p->u32DBAnAddress = BA0_DBA0;
-                       p->u32DCAnAddress = BA0_DCA0;
-                       p->u32DBCnAddress = BA0_DBC0;
-                       p->u32DCCnAddress = BA0_DCC0;
-                       p->u32DMRnAddress = BA0_DMR0;
-                       p->u32DCRnAddress = BA0_DCR0;
-                       p->u32HDSRnAddress = BA0_HDSR0;
-                       break;
-               }
-
-               case 1: /* capture */
-               {
-                       p->u32DBAnAddress = BA0_DBA1;
-                       p->u32DCAnAddress = BA0_DCA1;
-                       p->u32DBCnAddress = BA0_DBC1;
-                       p->u32DCCnAddress = BA0_DCC1;
-                       p->u32DMRnAddress = BA0_DMR1;
-                       p->u32DCRnAddress = BA0_DCR1;
-                       p->u32HDSRnAddress = BA0_HDSR1;
-                       break;
-               }
-
-               case 2:
-               {
-                       p->u32DBAnAddress = BA0_DBA2;
-                       p->u32DCAnAddress = BA0_DCA2;
-                       p->u32DBCnAddress = BA0_DBC2;
-                       p->u32DCCnAddress = BA0_DCC2;
-                       p->u32DMRnAddress = BA0_DMR2;
-                       p->u32DCRnAddress = BA0_DCR2;
-                       p->u32HDSRnAddress = BA0_HDSR2;
-                       break;
-               }
-
-               case 3:
-               {
-                       p->u32DBAnAddress = BA0_DBA3;
-                       p->u32DCAnAddress = BA0_DCA3;
-                       p->u32DBCnAddress = BA0_DBC3;
-                       p->u32DCCnAddress = BA0_DCC3;
-                       p->u32DMRnAddress = BA0_DMR3;
-                       p->u32DCRnAddress = BA0_DCR3;
-                       p->u32HDSRnAddress = BA0_HDSR3;
-                       break;
-               }
-               default:
-                       break;
-       }
-
-//
-// Initialize the dma values for this pipeline
-//
-       p->u32DBAnValue = readl(s->pBA0 + p->u32DBAnAddress);
-       p->u32DBCnValue = readl(s->pBA0 + p->u32DBCnAddress);
-       p->u32DMRnValue = readl(s->pBA0 + p->u32DMRnAddress);
-       p->u32DCRnValue = readl(s->pBA0 + p->u32DCRnAddress);
-
-}
-
-static void __devinit cs4281_InitPM(struct cs4281_state *s)
-{
-       int i;
-       struct cs4281_pipeline *p;
-
-       for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-       {
-               p = &s->pl[i];
-               p->number = i;
-               cs4281_BuildDMAengine(p,s);
-               cs4281_BuildFIFO(p,s);
-       /*
-       * currently only  2 pipelines are used
-       * so, only set the valid bit on the playback and capture.
-       */
-               if( (i == CS4281_PLAYBACK_PIPELINE_NUMBER) || 
-                       (i == CS4281_CAPTURE_PIPELINE_NUMBER))
-                       p->flags |= CS4281_PIPELINE_VALID;
-       }
-       s->pm.u32SSPM_BITS = 0x7e;  /* rev c, use 0x7c for rev a or b */
-}
-#endif
-
-static int __devinit cs4281_probe(struct pci_dev *pcidev,
-                                 const struct pci_device_id *pciid)
-{
-       struct cs4281_state *s;
-       dma_addr_t dma_mask;
-       mm_segment_t fs;
-       int i, val;
-       unsigned int temp1, temp2;
-
-       CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
-                 printk(KERN_INFO "cs4281: probe()+\n"));
-
-       if (pci_enable_device(pcidev)) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: pci_enable_device() failed\n"));
-               return -1;
-       }
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM) ||
-           !(pci_resource_flags(pcidev, 1) & IORESOURCE_MEM)) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe()- Memory region not assigned\n"));
-               return -ENODEV;
-       }
-       if (pcidev->irq == 0) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() IRQ not assigned\n"));
-               return -ENODEV;
-       }
-       dma_mask = 0xffffffff;  /* this enables playback and recording */
-       i = pci_set_dma_mask(pcidev, dma_mask);
-       if (i) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                     "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
-               return i;
-       }
-       if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                     "cs4281: probe() no memory for state struct.\n"));
-               return -1;
-       }
-       memset(s, 0, sizeof(struct cs4281_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->open_wait_adc);
-       init_waitqueue_head(&s->open_wait_dac);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_sem);
-       mutex_init(&s->open_sem_adc);
-       mutex_init(&s->open_sem_dac);
-       spin_lock_init(&s->lock);
-       s->pBA0phys = pci_resource_start(pcidev, 0);
-       s->pBA1phys = pci_resource_start(pcidev, 1);
-
-       /* Convert phys to linear. */
-       s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);
-       if (!s->pBA0) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: BA0 I/O mapping failed. Skipping part.\n"));
-               goto err_free;
-       }
-       s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);
-       if (!s->pBA1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: BA1 I/O mapping failed. Skipping part.\n"));
-               goto err_unmap;
-       }
-
-       temp1 = readl(s->pBA0 + BA0_PCICFG00);
-       temp2 = readl(s->pBA0 + BA0_PCICFG04);
-
-       CS_DBGOUT(CS_INIT, 2,
-                 printk(KERN_INFO
-                        "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=%p pBA1=%p \n",
-                        (unsigned) temp1, (unsigned) temp2, s->pBA0, s->pBA1));
-       CS_DBGOUT(CS_INIT, 2,
-                 printk(KERN_INFO
-                        "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
-                        (unsigned) s->pBA0phys, (unsigned) s->pBA1phys));
-
-#ifndef NOT_CS4281_PM
-       s->pm.flags = CS4281_PM_IDLE;
-#endif
-       temp1 = cs4281_hw_init(s);
-       if (temp1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: cs4281_hw_init() failed. Skipping part.\n"));
-               goto err_irq;
-       }
-       s->magic = CS4281_MAGIC;
-       s->pcidev = pcidev;
-       s->irq = pcidev->irq;
-       if (request_irq
-           (s->irq, cs4281_interrupt, IRQF_SHARED, "Crystal CS4281", s)) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-                         printk(KERN_ERR "cs4281: irq %u in use\n", s->irq));
-               goto err_irq;
-       }
-       if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) <
-           0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_dsp() failed.\n"));
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) <
-           0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_mixer() failed.\n"));
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_midi() failed.\n"));
-               goto err_dev3;
-       }
-#ifndef NOT_CS4281_PM
-       cs4281_InitPM(s);
-       s->pm.flags |= CS4281_PM_NOT_REGISTERED;
-#endif
-
-       pci_set_master(pcidev); // enable bus mastering 
-
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
-       for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
-       }
-       val = 1;                // enable mic preamp 
-       mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
-       set_fs(fs);
-
-       pci_set_drvdata(pcidev, s);
-       list_add(&s->list, &cs4281_devs);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-               "cs4281: probe()- device allocated successfully\n"));
-       return 0;
-
-      err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
-      err_dev2:
-       unregister_sound_dsp(s->dev_audio);
-      err_dev1:
-       free_irq(s->irq, s);
-      err_irq:
-       iounmap(s->pBA1);
-      err_unmap:
-       iounmap(s->pBA0);
-      err_free:
-       kfree(s);
-
-       CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO
-               "cs4281: probe()- no device allocated\n"));
-       return -ENODEV;
-} // probe_cs4281
-
-
-// --------------------------------------------------------------------- 
-
-static void __devexit cs4281_remove(struct pci_dev *pci_dev)
-{
-       struct cs4281_state *s = pci_get_drvdata(pci_dev);
-       // stop DMA controller 
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       iounmap(s->pBA1);
-       iounmap(s->pBA0);
-       pci_set_drvdata(pci_dev,NULL);
-       list_del(&s->list);
-       kfree(s);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-                "cs4281: cs4281_remove()-: remove successful\n"));
-}
-
-static struct pci_device_id cs4281_pci_tbl[] = {
-       {
-               .vendor    = PCI_VENDOR_ID_CIRRUS,
-               .device    = PCI_DEVICE_ID_CRYSTAL_CS4281,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl);
-
-static struct pci_driver cs4281_pci_driver = {
-       .name     = "cs4281",
-       .id_table = cs4281_pci_tbl,
-       .probe    = cs4281_probe,
-       .remove   = __devexit_p(cs4281_remove),
-       .suspend  = CS4281_SUSPEND_TBL,
-       .resume   = CS4281_RESUME_TBL,
-};
-
-static int __init cs4281_init_module(void)
-{
-       int rtn = 0;
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
-               "cs4281: cs4281_init_module()+ \n"));
-       printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
-              __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
-              CS4281_ARCH);
-       rtn = pci_register_driver(&cs4281_pci_driver);
-
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn));
-       return rtn;
-}
-
-static void __exit cs4281_cleanup_module(void)
-{
-       pci_unregister_driver(&cs4281_pci_driver);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
-}
-// --------------------------------------------------------------------- 
-
-MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
-MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
-MODULE_LICENSE("GPL");
-
-// --------------------------------------------------------------------- 
-
-module_init(cs4281_init_module);
-module_exit(cs4281_cleanup_module);
-
diff --git a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c
deleted file mode 100644 (file)
index 90cbd76..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281pm.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-
-#ifndef NOT_CS4281_PM
-#include <linux/pm.h>
-
-static int cs4281_suspend(struct cs4281_state *s);
-static int cs4281_resume(struct cs4281_state *s);
-/* 
-* for now (12/22/00) only enable the pm_register PM support.
-* allow these table entries to be null.
-#define CS4281_SUSPEND_TBL cs4281_suspend_tbl
-#define CS4281_RESUME_TBL cs4281_resume_tbl
-*/
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-
-#else /* CS4281_PM */
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-#endif /* CS4281_PM */
-
diff --git a/sound/oss/cs4281/cs4281pm.h b/sound/oss/cs4281/cs4281pm.h
deleted file mode 100644 (file)
index b44fdc9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef NOT_CS4281_PM
-/*******************************************************************************
-*
-*      "cs4281pm.h" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-/* general pm definitions */
-#define CS4281_AC97_HIGHESTREGTORESTORE 0x26
-#define CS4281_AC97_NUMBER_RESTORE_REGS (CS4281_AC97_HIGHESTREGTORESTORE/2-1)
-
-/* pipeline definitions */
-#define CS4281_NUMBER_OF_PIPELINES     4
-#define CS4281_PIPELINE_VALID          0x0001
-#define CS4281_PLAYBACK_PIPELINE_NUMBER        0x0000
-#define CS4281_CAPTURE_PIPELINE_NUMBER         0x0001
-
-/* PM state defintions */
-#define CS4281_PM_NOT_REGISTERED       0x1000
-#define CS4281_PM_IDLE                 0x0001
-#define CS4281_PM_SUSPENDING           0x0002
-#define CS4281_PM_SUSPENDED            0x0004
-#define CS4281_PM_RESUMING             0x0008
-#define CS4281_PM_RESUMED              0x0010
-
-struct cs4281_pm {
-       unsigned long flags;
-       u32 u32CLKCR1_SAVE,u32SSPMValue,u32PPLVCvalue,u32PPRVCvalue;
-       u32 u32FMLVCvalue,u32FMRVCvalue,u32GPIORvalue,u32JSCTLvalue,u32SSCR;
-       u32 u32SRCSA,u32DacASR,u32AdcASR,u32DacSR,u32AdcSR,u32MIDCR_Save;
-       u32 u32SSPM_BITS;
-       u32 ac97[CS4281_AC97_NUMBER_RESTORE_REGS];
-       u32 u32AC97_master_volume, u32AC97_headphone_volume, u32AC97_master_volume_mono;
-       u32 u32AC97_pcm_out_volume, u32AC97_powerdown, u32AC97_general_purpose;
-       u32 u32hwptr_playback,u32hwptr_capture;
-};
-
-struct cs4281_pipeline {
-       unsigned flags;
-       unsigned number;
-       u32 u32DBAnValue,u32DBCnValue,u32DMRnValue,u32DCRnValue;
-       u32 u32DBAnAddress,u32DCAnAddress,u32DBCnAddress,u32DCCnAddress;
-       u32 u32DMRnAddress,u32DCRnAddress,u32HDSRnAddress;
-       u32 u32DBAn_Save,u32DBCn_Save,u32DMRn_Save,u32DCRn_Save;
-       u32 u32DCCn_Save,u32DCAn_Save;
-/* 
-* technically, these are fifo variables, but just map the 
-* first fifo with the first pipeline and then use the fifo
-* variables inside of the pipeline struct.
-*/
-       u32 u32FCRn_Save,u32FSICn_Save;
-       u32 u32FCRnValue,u32FCRnAddress,u32FSICnValue,u32FSICnAddress;
-       u32 u32FPDRnValue,u32FPDRnAddress;
-};
-#endif
index f65a90469d8a329ac5f2766417f51861647ae75c..08274c995d0625e78cabd097617ad1e4a3b290b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/dev_table.c
+ * sound/oss/dev_table.c
  *
  * Device call tables.
  *
 
 #include <linux/init.h>
 
-#define _DEV_TABLE_C_
 #include "sound_config.h"
 
+struct audio_operations *audio_devs[MAX_AUDIO_DEV];
+EXPORT_SYMBOL(audio_devs);
+
+int num_audiodevs;
+EXPORT_SYMBOL(num_audiodevs);
+
+struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
+EXPORT_SYMBOL(mixer_devs);
+
+int num_mixers;
+EXPORT_SYMBOL(num_mixers);
+
+struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
+EXPORT_SYMBOL(synth_devs);
+
+int num_synths;
+
+struct midi_operations *midi_devs[MAX_MIDI_DEV];
+EXPORT_SYMBOL(midi_devs);
+
+int num_midis;
+EXPORT_SYMBOL(num_midis);
+
+struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
+       &default_sound_timer, NULL
+};
+EXPORT_SYMBOL(sound_timer_devs);
+
+int num_sound_timers = 1;
+
+
 static int sound_alloc_audiodev(void);
 
 int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
@@ -75,6 +105,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
        audio_init_devices();
        return num;
 }
+EXPORT_SYMBOL(sound_install_audiodrv);
 
 int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
        int driver_size, void *devc)
@@ -113,6 +144,7 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
        mixer_devs[n] = op;
        return n;
 }
+EXPORT_SYMBOL(sound_install_mixer);
 
 void sound_unload_audiodev(int dev)
 {
@@ -122,6 +154,7 @@ void sound_unload_audiodev(int dev)
                unregister_sound_dsp((dev<<4)+3);
        }
 }
+EXPORT_SYMBOL(sound_unload_audiodev);
 
 static int sound_alloc_audiodev(void)
 { 
@@ -144,6 +177,7 @@ int sound_alloc_mididev(void)
                num_midis = i + 1;
        return i;
 }
+EXPORT_SYMBOL(sound_alloc_mididev);
 
 int sound_alloc_synthdev(void)
 {
@@ -158,6 +192,7 @@ int sound_alloc_synthdev(void)
        }
        return -1;
 }
+EXPORT_SYMBOL(sound_alloc_synthdev);
 
 int sound_alloc_mixerdev(void)
 {
@@ -169,6 +204,7 @@ int sound_alloc_mixerdev(void)
                num_mixers = i + 1;
        return i;
 }
+EXPORT_SYMBOL(sound_alloc_mixerdev);
 
 int sound_alloc_timerdev(void)
 {
@@ -183,6 +219,7 @@ int sound_alloc_timerdev(void)
        }
        return -1;
 }
+EXPORT_SYMBOL(sound_alloc_timerdev);
 
 void sound_unload_mixerdev(int dev)
 {
@@ -192,6 +229,7 @@ void sound_unload_mixerdev(int dev)
                num_mixers--;
        }
 }
+EXPORT_SYMBOL(sound_unload_mixerdev);
 
 void sound_unload_mididev(int dev)
 {
@@ -200,15 +238,19 @@ void sound_unload_mididev(int dev)
                unregister_sound_midi((dev<<4)+2);
        }
 }
+EXPORT_SYMBOL(sound_unload_mididev);
 
 void sound_unload_synthdev(int dev)
 {
        if (dev != -1)
                synth_devs[dev] = NULL;
 }
+EXPORT_SYMBOL(sound_unload_synthdev);
 
 void sound_unload_timerdev(int dev)
 {
        if (dev != -1)
                sound_timer_devs[dev] = NULL;
 }
+EXPORT_SYMBOL(sound_unload_timerdev);
+
index adf1d625b576cc19af1bc7b574690ae7c5cf5e9b..b7617bee6388f13be8fa4bf842c6c88990faef90 100644 (file)
@@ -352,22 +352,8 @@ struct sound_timer_operations
        void (*arm_timer)(int dev, long time);
 };
 
-#ifdef _DEV_TABLE_C_   
-struct audio_operations *audio_devs[MAX_AUDIO_DEV];
-int num_audiodevs;
-struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
-int num_mixers;
-struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV];
-int num_synths;
-struct midi_operations *midi_devs[MAX_MIDI_DEV];
-int num_midis;
-
 extern struct sound_timer_operations default_sound_timer;
-struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
-       &default_sound_timer, NULL
-}; 
-int num_sound_timers = 1;
-#else
+
 extern struct audio_operations *audio_devs[MAX_AUDIO_DEV];
 extern int num_audiodevs;
 extern struct mixer_operations *mixer_devs[MAX_MIXER_DEV];
@@ -378,7 +364,6 @@ extern struct midi_operations *midi_devs[MAX_MIDI_DEV];
 extern int num_midis;
 extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV];
 extern int num_sound_timers;
-#endif /* _DEV_TABLE_C_ */
 
 extern int sound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc *info);
 void sound_timer_init (struct sound_lowlev_timer *t, char *name);
diff --git a/sound/oss/dm.h b/sound/oss/dm.h
deleted file mode 100644 (file)
index 14a9059..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef _DRIVERS_SOUND_DM_H
-#define _DRIVERS_SOUND_DM_H
-
-/*
- *     Definitions of the 'direct midi sound' interface used
- *     by the newer commercial OSS package. We should export
- *     this to userland somewhere in glibc later.
- */
-
-/*
- * Data structure composing an FM "note" or sound event.
- */
-
-struct dm_fm_voice
-{
-       u8 op;
-       u8 voice;
-       u8 am;
-       u8 vibrato;
-       u8 do_sustain;
-       u8 kbd_scale;
-       u8 harmonic;
-       u8 scale_level;
-       u8 volume;
-       u8 attack;
-       u8 decay;
-       u8 sustain;
-       u8 release;
-       u8 feedback;
-       u8 connection;
-       u8 left;
-       u8 right;
-       u8 waveform;
-};
-
-/*
- *     This describes an FM note by its voice, octave, frequency number (10bit)
- *     and key on/off.
- */
-
-struct dm_fm_note
-{
-       u8 voice;
-       u8 octave;
-       u32 fnum;
-       u8 key_on;
-};
-
-/*
- * FM parameters that apply globally to all voices, and thus are not "notes"
- */
-
-struct dm_fm_params
-{
-       u8 am_depth;
-       u8 vib_depth;
-       u8 kbd_split;
-       u8 rhythm;
-
-       /* This block is the percussion instrument data */
-       u8 bass;
-       u8 snare;
-       u8 tomtom;
-       u8 cymbal;
-       u8 hihat;
-};
-
-/*
- *     FM mode ioctl settings
- */
-#define FM_IOCTL_RESET        0x20
-#define FM_IOCTL_PLAY_NOTE    0x21
-#define FM_IOCTL_SET_VOICE    0x22
-#define FM_IOCTL_SET_PARAMS   0x23
-#define FM_IOCTL_SET_MODE     0x24
-#define FM_IOCTL_SET_OPL      0x25
-
-#endif
index 15ce7119c5f45ac605181566b2359712ae4f84f5..b256c0401161a8ad97c1c5dd680291b907fe284f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/dmabuf.c
+ * sound/oss/dmabuf.c
  *
  * The DMA buffer manager for digitized voice applications
  */
@@ -926,6 +926,7 @@ int DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
        sound_start_dma(dmap, physaddr, count, dma_mode);
        return count;
 }
+EXPORT_SYMBOL(DMAbuf_start_dma);
 
 static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode)
 {
@@ -1055,6 +1056,8 @@ void DMAbuf_outputintr(int dev, int notify_only)
                do_outputintr(dev, notify_only);
        spin_unlock_irqrestore(&dmap->lock,flags);
 }
+EXPORT_SYMBOL(DMAbuf_outputintr);
+
 /* called with dmap->lock held in irq context */
 static void do_inputintr(int dev)
 {
@@ -1154,36 +1157,7 @@ void DMAbuf_inputintr(int dev)
                do_inputintr(dev);
        spin_unlock_irqrestore(&dmap->lock,flags);
 }
-
-int DMAbuf_open_dma(int dev)
-{
-       /*
-        *    NOTE!  This routine opens only the primary DMA channel (output).
-        */
-       struct audio_operations *adev = audio_devs[dev];
-       int err;
-
-       if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)
-               return -EBUSY;
-       dma_init_buffers(adev->dmap_out);
-       adev->dmap_out->flags |= DMA_ALLOC_DONE;
-       adev->dmap_out->fragment_size = adev->dmap_out->buffsize;
-
-       if (adev->dmap_out->dma >= 0) {
-               unsigned long flags;
-
-               flags=claim_dma_lock();
-               clear_dma_ff(adev->dmap_out->dma);
-               disable_dma(adev->dmap_out->dma);
-               release_dma_lock(flags);
-       }
-       return 0;
-}
-
-void DMAbuf_close_dma(int dev)
-{
-       close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);
-}
+EXPORT_SYMBOL(DMAbuf_inputintr);
 
 void DMAbuf_init(int dev, int dma1, int dma2)
 {
@@ -1192,12 +1166,6 @@ void DMAbuf_init(int dev, int dma1, int dma2)
         * NOTE! This routine could be called several times.
         */
 
-       /* drag in audio_syms.o */
-       {
-               extern char audio_syms_symbol;
-               audio_syms_symbol = 0;
-       }
-
        if (adev && adev->dmap_out == NULL) {
                if (adev->d == NULL)
                        panic("OSS: audio_devs[%d]->d == NULL\n", dev);
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
deleted file mode 100644 (file)
index 13f4831..0000000
+++ /dev/null
@@ -1,2819 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      es1370.c  --  Ensoniq ES1370/Asahi Kasei AK4531 audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   lineout  if 1 the LINE jack is used as an output instead of an input.
- *            LINE then contains the unmixed dsp output. This can be used
- *            to make the card a four channel one: use dsp to output two
- *            channels to LINE and dac to output the other two channels to
- *            SPKR. Set the mixer to only output synth to SPKR.
- *   micbias  sets the +5V bias to the mic if using an electretmic.
- *            
- *
- *  Note: sync mode is not yet supported (i.e. running dsp and dac from the same
- *  clock source)
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/dsp1   additional DAC, like /dev/dsp, but output only,
- *              only 5512, 11025, 22050 and 44100 samples/s,
- *              outputs to mixer "SYNTH" setting
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- *  to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- *  there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- *  Revision history
- *    26.03.1998   0.1   Initial release
- *    31.03.1998   0.2   Fix bug in GETOSPACE
- *    04.04.1998   0.3   Make it work (again) under 2.0.33
- *                       Fix mixer write operation not returning the actual
- *                       settings
- *    05.04.1998   0.4   First attempt at using the new PCI stuff
- *    29.04.1998   0.5   Fix hang when ^C is pressed on amp
- *    07.05.1998   0.6   Don't double lock around stop_*() in *_release()
- *    10.05.1998   0.7   First stab at a simple midi interface (no bells&whistles)
- *    14.05.1998   0.8   Don't allow excessive interrupt rates
- *    08.06.1998   0.9   First release using Alan Cox' soundcore instead of
- *                       miscdevice
- *    05.07.1998   0.10  Fixed the driver to correctly maintin OSS style volume
- *                       settings (not sure if this should be standard)
- *                       Fixed many references: f_flags should be f_mode
- *                       -- Gerald Britton <gbritton@mit.edu>
- *    03.08.1998   0.11  Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *                       Fixed mixer table thanks to Hakan.Lennestal@lu.erisoft.se
- *                       On module startup, set DAC2 to 11kSPS instead of 5.5kSPS,
- *                       as it produces an annoying ssssh in the lower sampling rate
- *                       Do not include modversions.h
- *    22.08.1998   0.12  Mixer registers actually have 5 instead of 4 bits
- *                       pointed out by Itai Nahshon
- *    31.08.1998   0.13  Fix realplayer problems - dac.count issues
- *    08.10.1998   0.14  Joystick support fixed
- *                      -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
- *    10.12.1998   0.15  Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.16  Don't wake up app until there are fragsize bytes to read/write
- *    06.01.1999   0.17  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.18  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.19  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.20  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: joystick address handling might still be wrong on archs
- *                       other than i386
- *    10.05.1999   0.21  Added support for an electret mic for SB PCI64
- *                       to the Linux kernel sound driver. This mod also straighten
- *                       out the question marks around the mic impedance setting
- *                       (micz). From Kim.Berts@fisub.mail.abb.com
- *    11.05.1999   0.22  Implemented the IMIX call to mute recording monitor.
- *                       Guenter Geiger <geiger@epy.co.at>
- *    15.06.1999   0.23  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.24  Add pci_set_master
- *    02.08.1999   0.25  Added workaround for the "phantom write" bug first
- *                       documented by Dave Sharpless from Anchor Games
- *    03.08.1999   0.26  adapt to Linus' new __setup/__initcall
- *                       added kernel command line option "es1370=joystick[,lineout[,micbias]]"
- *                       removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge
- *    12.08.1999   0.27  module_init/__setup fixes
- *    19.08.1999   0.28  SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it>
- *    31.08.1999   0.29  add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.30  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.31  More waitqueue races fixed
- *    08.01.2000   0.32  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *    07.02.2000   0.33  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.34  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.35  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    07.01.2001   0.36  Timeout change in wrcodec as requested by Frank Klemm <pfk@fuchs.offl.uni-jena.de>
- *    31.01.2001   0.37  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    03.01.2003   0.38  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- * some important things missing in Ensoniq documentation:
- *
- * Experimental PCLKDIV results:  play the same waveforms on both DAC1 and DAC2
- * and vary PCLKDIV to obtain zero beat.
- *  5512sps:  254
- * 44100sps:   30
- * seems to be fs = 1411200/(PCLKDIV+2)
- *
- * should find out when curr_sample_ct is cleared and
- * where exactly the CCB fetches data
- *
- * The card uses a 22.5792 MHz crystal.
- * The LINEIN jack may be converted to an AOUT jack by
- * setting pin 47 (XCTL0) of the ES1370 to high.
- * Pin 48 (XCTL1) of the ES1370 sets the +5V bias for an electretmic
- * 
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ        0x1274    
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1370
-#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
-#endif
-
-#define ES1370_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1370)
-
-#define ES1370_EXTENT             0x40
-#define JOY_EXTENT                8
-
-#define ES1370_REG_CONTROL        0x00
-#define ES1370_REG_STATUS         0x04
-#define ES1370_REG_UART_DATA      0x08
-#define ES1370_REG_UART_STATUS    0x09
-#define ES1370_REG_UART_CONTROL   0x09
-#define ES1370_REG_UART_TEST      0x0a
-#define ES1370_REG_MEMPAGE        0x0c
-#define ES1370_REG_CODEC          0x10
-#define ES1370_REG_SERIAL_CONTROL 0x20
-#define ES1370_REG_DAC1_SCOUNT    0x24
-#define ES1370_REG_DAC2_SCOUNT    0x28
-#define ES1370_REG_ADC_SCOUNT     0x2c
-
-#define ES1370_REG_DAC1_FRAMEADR    0xc30
-#define ES1370_REG_DAC1_FRAMECNT    0xc34
-#define ES1370_REG_DAC2_FRAMEADR    0xc38
-#define ES1370_REG_DAC2_FRAMECNT    0xc3c
-#define ES1370_REG_ADC_FRAMEADR     0xd30
-#define ES1370_REG_ADC_FRAMECNT     0xd34
-#define ES1370_REG_PHANTOM_FRAMEADR 0xd38
-#define ES1370_REG_PHANTOM_FRAMECNT 0xd3c
-
-#define ES1370_FMT_U8_MONO     0
-#define ES1370_FMT_U8_STEREO   1
-#define ES1370_FMT_S16_MONO    2
-#define ES1370_FMT_S16_STEREO  3
-#define ES1370_FMT_STEREO      1
-#define ES1370_FMT_S16         2
-#define ES1370_FMT_MASK        3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-static const unsigned dac1_samplerate[] = { 5512, 11025, 22050, 44100 };
-
-#define DAC2_SRTODIV(x) (((1411200+(x)/2)/(x))-2)
-#define DAC2_DIVTOSR(x) (1411200/((x)+2))
-
-#define CTRL_ADC_STOP   0x80000000  /* 1 = ADC stopped */
-#define CTRL_XCTL1      0x40000000  /* electret mic bias */
-#define CTRL_OPEN       0x20000000  /* no function, can be read and written */
-#define CTRL_PCLKDIV    0x1fff0000  /* ADC/DAC2 clock divider */
-#define CTRL_SH_PCLKDIV 16
-#define CTRL_MSFMTSEL   0x00008000  /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_M_SBB      0x00004000  /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */
-#define CTRL_WTSRSEL    0x00003000  /* DAC1 clock freq: 0=5512, 1=11025, 2=22050, 3=44100 */
-#define CTRL_SH_WTSRSEL 12
-#define CTRL_DAC_SYNC   0x00000800  /* 1 = DAC2 runs off DAC1 clock */
-#define CTRL_CCB_INTRM  0x00000400  /* 1 = CCB "voice" ints enabled */
-#define CTRL_M_CB       0x00000200  /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_XCTL0      0x00000100  /* 0 = Line in, 1 = Line out */
-#define CTRL_BREQ       0x00000080  /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN    0x00000040  /* enable DAC1 */
-#define CTRL_DAC2_EN    0x00000020  /* enable DAC2 */
-#define CTRL_ADC_EN     0x00000010  /* enable ADC */
-#define CTRL_UART_EN    0x00000008  /* enable MIDI uart */
-#define CTRL_JYSTK_EN   0x00000004  /* enable Joystick port (presumably at address 0x200) */
-#define CTRL_CDC_EN     0x00000002  /* enable serial (CODEC) interface */
-#define CTRL_SERR_DIS   0x00000001  /* 1 = disable PCI SERR signal */
-
-#define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
-#define STAT_CSTAT      0x00000400  /* 1 = codec busy or codec write in progress */
-#define STAT_CBUSY      0x00000200  /* 1 = codec busy */
-#define STAT_CWRIP      0x00000100  /* 1 = codec write in progress */
-#define STAT_VC         0x00000060  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC      5
-#define STAT_MCCB       0x00000010  /* CCB int pending */
-#define STAT_UART       0x00000008  /* UART int pending */
-#define STAT_DAC1       0x00000004  /* DAC1 int pending */
-#define STAT_DAC2       0x00000002  /* DAC2 int pending */
-#define STAT_ADC        0x00000001  /* ADC int pending */
-
-#define USTAT_RXINT     0x80        /* UART rx int pending */
-#define USTAT_TXINT     0x04        /* UART tx int pending */
-#define USTAT_TXRDY     0x02        /* UART tx ready */
-#define USTAT_RXRDY     0x01        /* UART rx ready */
-
-#define UCTRL_RXINTEN   0x80        /* 1 = enable RX ints */
-#define UCTRL_TXINTEN   0x60        /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20        /* enable TX int */
-#define UCTRL_CNTRL     0x03        /* control field */
-#define UCTRL_CNTRL_SWR 0x03        /* software reset command */
-
-#define SCTRL_P2ENDINC    0x00380000  /*  */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC     0x00070000  /*  */
-#define SCTRL_SH_P2STINC  16
-#define SCTRL_R1LOOPSEL   0x00008000  /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL   0x00004000  /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL   0x00002000  /* 0 = loop mode */
-#define SCTRL_P2PAUSE     0x00001000  /* 1 = pause mode */
-#define SCTRL_P1PAUSE     0x00000800  /* 1 = pause mode */
-#define SCTRL_R1INTEN     0x00000400  /* enable interrupt */
-#define SCTRL_P2INTEN     0x00000200  /* enable interrupt */
-#define SCTRL_P1INTEN     0x00000100  /* enable interrupt */
-#define SCTRL_P1SCTRLD    0x00000080  /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN    0x00000040  /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB       0x00000020  /* 1 = 16bit */
-#define SCTRL_R1SMB       0x00000010  /* 1 = stereo */
-#define SCTRL_R1FMT       0x00000030  /* format mask */
-#define SCTRL_SH_R1FMT    4
-#define SCTRL_P2SEB       0x00000008  /* 1 = 16bit */
-#define SCTRL_P2SMB       0x00000004  /* 1 = stereo */
-#define SCTRL_P2FMT       0x0000000c  /* format mask */
-#define SCTRL_SH_P2FMT    2
-#define SCTRL_P1SEB       0x00000002  /* 1 = 16bit */
-#define SCTRL_P1SMB       0x00000001  /* 1 = stereo */
-#define SCTRL_P1FMT       0x00000003  /* format mask */
-#define SCTRL_SH_P1FMT    0
-
-/* misc stuff */
-
-#define FMODE_DAC         4           /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-/* --------------------------------------------------------------------- */
-
-struct es1370_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of es1370 devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_dac;
-       int dev_midi;
-       
-       /* hardware resources */
-       unsigned long io; /* long for SPARC */
-       unsigned int irq;
-
-       /* mixer registers; there is no HW readback */
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-               unsigned int imix;
-       } mix;
-
-       /* wave stuff */
-       unsigned ctrl;
-       unsigned sctrl;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac1, dma_dac2, dma_adc;
-
-       /* The following buffer is used to point the phantom write channel to. */
-       unsigned char *bugbuf_cpu;
-       dma_addr_t bugbuf_dma;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#ifdef SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-
-       struct mutex mutex;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct es1370_state *s, unsigned char idx, unsigned char data)
-{
-       unsigned long tmo = jiffies + HZ/10, j;
-       
-       do {
-               j = jiffies;
-               if (!(inl(s->io+ES1370_REG_STATUS) & STAT_CSTAT)) {
-                       outw((((unsigned short)idx)<<8)|data, s->io+ES1370_REG_CODEC);
-                       return;
-               }
-               schedule();
-       } while ((signed)(tmo-j) > 0);
-       printk(KERN_ERR "es1370: write to codec register timeout\n");
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_ADC_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac1(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC1_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac2(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC2_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac1(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
-           && s->dma_dac1.ready) {
-               s->ctrl |= CTRL_DAC1_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac1.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac2(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
-           && s->dma_dac2.ready) {
-               s->ctrl |= CTRL_DAC2_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | 
-                                        SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
-                       (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | 
-                       (0 << SCTRL_SH_P2STINC);
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac2.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               s->ctrl |= CTRL_ADC_EN;
-               s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_adc.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct es1370_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1370_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       fmt &= ES1370_FMT_MASK;
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       memset(db->rawbuf, (fmt & ES1370_FMT_S16) ? 0 : 0x80, db->dmasize);
-       outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       outl(db->dmaaddr, s->io+(reg & 0xff));
-       outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1370_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-                          (s->sctrl >> SCTRL_SH_R1FMT) & ES1370_FMT_MASK, ES1370_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1370_state *s)
-{
-       stop_dac2(s);
-       return prog_dmabuf(s, &s->dma_dac2, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-                          (s->sctrl >> SCTRL_SH_P2FMT) & ES1370_FMT_MASK, ES1370_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1370_state *s)
-{
-       stop_dac1(s);
-       return prog_dmabuf(s, &s->dma_dac1, dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL],
-                          (s->sctrl >> SCTRL_SH_P1FMT) & ES1370_FMT_MASK, ES1370_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1370_state *s, struct dmabuf *db, unsigned reg)
-{
-       unsigned hwptr, diff;
-
-       outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
-       diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
-       db->hwptr = hwptr;
-       return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *)buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1370_update_ptr(struct es1370_state *s)
-{
-       int diff;
-
-       /* update ADC pointer */
-       if (s->ctrl & CTRL_ADC_EN) {
-               diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT);
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->ctrl &= ~CTRL_ADC_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC1 pointer */
-       if (s->ctrl & CTRL_DAC1_EN) {
-               diff = get_hwptr(s, &s->dma_dac1, ES1370_REG_DAC1_FRAMECNT);
-               s->dma_dac1.total_bytes += diff;
-               if (s->dma_dac1.mapped) {
-                       s->dma_dac1.count += diff;
-                       if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                               wake_up(&s->dma_dac1.wait);
-               } else {
-                       s->dma_dac1.count -= diff;
-                       if (s->dma_dac1.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC1_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_dac1.error++;
-                       } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
-                               clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, 
-                                             s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
-                               s->dma_dac1.endcleared = 1;
-                       }
-                       if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
-                               wake_up(&s->dma_dac1.wait);
-               }
-       }
-       /* update DAC2 pointer */
-       if (s->ctrl & CTRL_DAC2_EN) {
-               diff = get_hwptr(s, &s->dma_dac2, ES1370_REG_DAC2_FRAMECNT);
-               s->dma_dac2.total_bytes += diff;
-               if (s->dma_dac2.mapped) {
-                       s->dma_dac2.count += diff;
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
-                               wake_up(&s->dma_dac2.wait);
-               } else {
-                       s->dma_dac2.count -= diff;
-                       if (s->dma_dac2.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC2_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_dac2.error++;
-                       } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
-                               clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, 
-                                             s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
-                               s->dma_dac2.endcleared = 1;
-                       }
-                       if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
-                               wake_up(&s->dma_dac2.wait);
-               }
-       }
-}
-
-/* hold spinlock for the following! */
-static void es1370_handle_midi(struct es1370_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       if (!(s->ctrl & CTRL_UART_EN))
-               return;
-       wake = 0;
-       while (inb(s->io+ES1370_REG_UART_STATUS) & USTAT_RXRDY) {
-               ch = inb(s->io+ES1370_REG_UART_DATA);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while ((inb(s->io+ES1370_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->io+ES1370_REG_UART_DATA);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-       outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1370_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1370_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct es1370_state *s = (struct es1370_state *)dev_id;
-       unsigned int intsrc, sctl;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inl(s->io+ES1370_REG_STATUS);
-       if (!(intsrc & 0x80000000))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       /* clear audio interrupts first */
-       sctl = s->sctrl;
-       if (intsrc & STAT_ADC)
-               sctl &= ~SCTRL_R1INTEN;
-       if (intsrc & STAT_DAC1)
-               sctl &= ~SCTRL_P1INTEN;
-       if (intsrc & STAT_DAC2)
-               sctl &= ~SCTRL_P2INTEN;
-       outl(sctl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       es1370_update_ptr(s);
-       es1370_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "es1370: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != ES1370_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static const struct {
-       unsigned volidx:4;
-       unsigned left:4;
-       unsigned right:4;
-       unsigned stereo:1;
-       unsigned recmask:13;
-       unsigned avail:1;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 },   /* master */
-       [SOUND_MIXER_PCM]    = { 1, 0x2, 0x3, 1, 0x0400, 1 },   /* voice */
-       [SOUND_MIXER_SYNTH]  = { 2, 0x4, 0x5, 1, 0x0060, 1 },   /* FM */
-       [SOUND_MIXER_CD]     = { 3, 0x6, 0x7, 1, 0x0006, 1 },   /* CD */
-       [SOUND_MIXER_LINE]   = { 4, 0x8, 0x9, 1, 0x0018, 1 },   /* Line */
-       [SOUND_MIXER_LINE1]  = { 5, 0xa, 0xb, 1, 0x1800, 1 },   /* AUX */
-       [SOUND_MIXER_LINE2]  = { 6, 0xc, 0x0, 0, 0x0100, 1 },   /* Mono1 */
-       [SOUND_MIXER_LINE3]  = { 7, 0xd, 0x0, 0, 0x0200, 1 },   /* Mono2 */
-       [SOUND_MIXER_MIC]    = { 8, 0xe, 0x0, 0, 0x0001, 1 },   /* Mic */
-       [SOUND_MIXER_OGAIN]  = { 9, 0xf, 0x0, 0, 0x0000, 1 }    /* mono out */
-};
-
-static void set_recsrc(struct es1370_state *s, unsigned int val)
-{
-       unsigned int i, j;
-
-       for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-               if (!(val & (1 << i)))
-                       continue;
-               if (!mixtable[i].recmask) {
-                       val &= ~(1 << i);
-                       continue;
-               }
-               j |= mixtable[i].recmask;
-       }
-       s->mix.recsrc = val;
-       wrcodec(s, 0x12, j & 0xd5);
-       wrcodec(s, 0x13, j & 0xaa);
-       wrcodec(s, 0x14, (j >> 8) & 0x17);
-       wrcodec(s, 0x15, (j >> 8) & 0x0f);
-       i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60;
-       if (!s->mix.imix) {
-               i &= 0xff60;  /* mute record and line monitor */
-       }
-       wrcodec(s, 0x10, i);
-       wrcodec(s, 0x11, i >> 8);
-}
-
-static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val;
-       unsigned char l, r, rl, rr;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               /* enable/disable/query mixer preamp */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       s->mix.micpreamp = !!val;
-                       wrcodec(s, 0x19, s->mix.micpreamp);
-               }
-               return put_user(s->mix.micpreamp, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               /* enable/disable/query use of linein as second lineout */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->ctrl |= CTRL_XCTL0;
-                       else
-                               s->ctrl &= ~CTRL_XCTL0;
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE3) {
-               /* enable/disable/query microphone impedance setting */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->ctrl |= CTRL_XCTL1;
-                       else
-                               s->ctrl &= ~CTRL_XCTL1;
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, p);
-       }
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strncpy(info.id, "ES1370", sizeof(info.id));
-               strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strncpy(info.id, "ES1370", sizeof(info.id));
-               strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(s->mix.recsrc, p);
-                       
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       val = SOUND_MASK_IMIX;
-                       for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].avail)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].recmask)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].stereo)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(0, p);
-               
-               case SOUND_MIXER_IMIX:
-                       return put_user(s->mix.imix, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-                                return -EINVAL;
-                       return put_user(s->mix.vol[mixtable[i].volidx], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-
-       case SOUND_MIXER_IMIX:
-               if (get_user(s->mix.imix, p))
-                       return -EFAULT;
-               set_recsrc(s, s->mix.recsrc);
-               return 0;
-
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_recsrc(s, val);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (mixtable[i].stereo) {
-                       r = (val >> 8) & 0xff;
-                       if (r > 100)
-                               r = 100;
-                       if (l < 7) {
-                               rl = 0x80;
-                               l = 0;
-                       } else {
-                               rl = 31 - ((l - 7) / 3);
-                               l = (31 - rl) * 3 + 7;
-                       }
-                       if (r < 7) {
-                               rr = 0x80;
-                               r = 0;
-                       } else {
-                               rr =  31 - ((r - 7) / 3);
-                               r = (31 - rr) * 3 + 7;
-                       }
-                       wrcodec(s, mixtable[i].right, rr);
-               } else { 
-                       if (mixtable[i].left == 15) {
-                               if (l < 2) {
-                                       rr = rl = 0x80;
-                                       r = l = 0;
-                               } else {
-                                       rl = 7 - ((l - 2) / 14);
-                                       r = l = (7 - rl) * 14 + 2;
-                               }
-                       } else {
-                               if (l < 7) {
-                                       rl = 0x80;
-                                       r = l = 0;
-                               } else {
-                                       rl = 31 - ((l - 7) / 3);
-                                       r = l = (31 - rl) * 3 + 7;
-                               }
-                       }
-               }
-               wrcodec(s, mixtable[i].left, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[mixtable[i].volidx] = ((unsigned int)r << 8) | l;
-#else
-               s->mix.vol[mixtable[i].volidx] = val;
-#endif
-                return put_user(s->mix.vol[mixtable[i].volidx], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int es1370_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct es1370_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1370_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = es1370_ioctl_mixdev,
-       .open           = es1370_open_mixdev,
-       .release        = es1370_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1370_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-       
-       if (s->dma_dac1.mapped || !s->dma_dac1.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac1.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac1.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2
-                       / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-static int drain_dac2(struct es1370_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac2.mapped || !s->dma_dac2.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac2.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac2.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2
-                       / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV);
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->mutex);
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               goto out;
-        
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       mutex_unlock(&s->mutex);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       mutex_lock(&s->mutex);
-                       if (s->dma_adc.mapped)
-                       {
-                               ret = -ENXIO;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-       }
-out:
-       mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac2.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->mutex);
-       if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-               goto out;
-       ret = 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac2.count < 0) {
-                       s->dma_dac2.count = 0;
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr;
-               }
-               swptr = s->dma_dac2.swptr;
-               cnt = s->dma_dac2.dmasize-swptr;
-               if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
-                       cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac2.enabled)
-                               start_dac2(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       mutex_unlock(&s->mutex);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;       
-                       }
-                       mutex_lock(&s->mutex);
-                       if (s->dma_dac2.mapped)
-                       {
-                       ret = -ENXIO;
-                       goto out;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_dac2.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac2.swptr = swptr;
-               s->dma_dac2.count += cnt;
-               s->dma_dac2.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac2.enabled)
-                       start_dac2(s);
-       }
-out:
-       mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac2.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       es1370_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac2.mapped) {
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = 0;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->mutex);
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac2(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_dac2;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_adc;
-       } else  {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot)) {
-               ret = -EAGAIN;
-               goto out;
-       }
-       db->mapped = 1;
-out:
-       mutex_unlock(&s->mutex);
-       unlock_kernel();
-       return ret;
-}
-
-static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, mapped, ret;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-                               return -EINVAL;
-                       if (val < 4000)
-                               val = 4000;
-                       if (val > 50000)
-                               val = 50000;
-                       stop_adc(s);
-                       stop_dac2(s);
-                       s->dma_adc.ready = s->dma_dac2.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV);
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_R1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_R1SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       s->dma_dac2.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_P2SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P2SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                }
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_R1SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SMB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_P2SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SMB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_R1SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SEB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_P2SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SEB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               AFMT_S16_LE : AFMT_U8, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-                                       return ret;
-                               s->dma_dac2.enabled = 1;
-                               start_dac2(s);
-                       } else {
-                               s->dma_dac2.enabled = 0;
-                               stop_dac2(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_dac2.fragsize;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac2.dmasize - count;
-                abinfo.fragstotal = s->dma_dac2.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                count = s->dma_dac2.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac2.total_bytes;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac2.fragshift;
-                cinfo.ptr = s->dma_dac2.hwptr;
-               if (s->dma_dac2.mapped)
-                       s->dma_dac2.count &= s->dma_dac2.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac2(s)))
-                               return val;
-                       return put_user(s->dma_dac2.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac2.ossfragshift = val & 0xffff;
-                       s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac2.ossfragshift < 4)
-                               s->dma_dac2.ossfragshift = 4;
-                       if (s->dma_dac2.ossfragshift > 15)
-                               s->dma_dac2.ossfragshift = 15;
-                       if (s->dma_dac2.ossmaxfrags < 4)
-                               s->dma_dac2.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac2.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?
-                               2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_READ|FMODE_WRITE)))
-               s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV);
-       if (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               s->sctrl &= ~SCTRL_R1FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_R1FMT;
-               else
-                       s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_R1FMT;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
-               s->dma_dac2.enabled = 1;
-               s->sctrl &= ~SCTRL_P2FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P2FMT;
-               else
-                       s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P2FMT;
-       }
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       mutex_init(&s->mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac2(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac2(s);
-               synchronize_irq(s->irq);
-               dealloc_dmabuf(s, &s->dma_dac2);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1370_read,
-       .write          = es1370_write,
-       .poll           = es1370_poll,
-       .ioctl          = es1370_ioctl,
-       .mmap           = es1370_mmap,
-       .open           = es1370_open,
-       .release        = es1370_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac1.mapped)
-               return -ENXIO;
-       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac1.count < 0) {
-                       s->dma_dac1.count = 0;
-                       s->dma_dac1.swptr = s->dma_dac1.hwptr;
-               }
-               swptr = s->dma_dac1.swptr;
-               cnt = s->dma_dac1.dmasize-swptr;
-               if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
-                       cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac1.enabled)
-                               start_dac1(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac1.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac1.swptr = swptr;
-               s->dma_dac1.count += cnt;
-               s->dma_dac1.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac1.enabled)
-                       start_dac1(s);
-       }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
-               return 0;
-       poll_wait(file, &s->dma_dac1.wait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       es1370_update_ptr(s);
-       if (s->dma_dac1.mapped) {
-               if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       } else {
-               if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       int ret;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       if (!(vma->vm_flags & VM_WRITE))
-               return -EINVAL;
-       lock_kernel();
-       if ((ret = prog_dmabuf_dac1(s)) != 0)
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << s->dma_dac1.buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-               goto out;
-       s->dma_dac1.mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       unsigned ctrl;
-       int val, ret;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               stop_dac1(s);
-               synchronize_irq(s->irq);
-               s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       for (ctrl = 0; ctrl <= 2; ctrl++)
-                               if (val < (dac1_samplerate[ctrl] + dac1_samplerate[ctrl+1]) / 2)
-                                       break;
-                       spin_lock_irqsave(&s->lock, flags);
-                       s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (ctrl << CTRL_SH_WTSRSEL);
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               stop_dac1(s);
-               s->dma_dac1.ready = 0;
-               spin_lock_irqsave(&s->lock, flags);
-               if (val)
-                       s->sctrl |= SCTRL_P1SMB;
-               else
-                       s->sctrl &= ~SCTRL_P1SMB;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (s->dma_dac1.mapped)
-                               return -EINVAL;
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val >= 2)
-                               s->sctrl |= SCTRL_P1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-               
-        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val == AFMT_S16_LE)
-                               s->sctrl |= SCTRL_P1SEB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SEB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
-        case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-                                               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val & PCM_ENABLE_OUTPUT) {
-                       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-                               return ret;
-                       s->dma_dac1.enabled = 1;
-                       start_dac1(s);
-               } else {
-                       s->dma_dac1.enabled = 0;
-                       stop_dac1(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_dac1.fragsize;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac1.dmasize - count;
-                abinfo.fragstotal = s->dma_dac1.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                count = s->dma_dac1.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac1.total_bytes;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac1.fragshift;
-                cinfo.ptr = s->dma_dac1.hwptr;
-               if (s->dma_dac1.mapped)
-                       s->dma_dac1.count &= s->dma_dac1.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if ((val = prog_dmabuf_dac1(s)))
-                       return val;
-                return put_user(s->dma_dac1.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               s->dma_dac1.ossfragshift = val & 0xffff;
-               s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
-               if (s->dma_dac1.ossfragshift < 4)
-                       s->dma_dac1.ossfragshift = 4;
-               if (s->dma_dac1.ossfragshift > 15)
-                       s->dma_dac1.ossfragshift = 15;
-               if (s->dma_dac1.ossmaxfrags < 4)
-                       s->dma_dac1.ossmaxfrags = 4;
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if (s->dma_dac1.subdivision)
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               s->dma_dac1.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open_dac(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (!((s->dev_dac ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-               /* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
-       if (file->f_mode & FMODE_READ)
-               return -EPERM;
-#endif
-       if (!(file->f_mode & FMODE_WRITE))
-               return -EINVAL;
-               file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DAC) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
-       s->dma_dac1.enabled = 1;
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (1 << CTRL_SH_WTSRSEL);
-       s->sctrl &= ~SCTRL_P1FMT;
-       if ((minor & 0xf) == SND_DEV_DSP16)
-               s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P1FMT;
-       else
-               s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P1FMT;
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= FMODE_DAC;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release_dac(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       drain_dac1(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       stop_dac1(s);
-       dealloc_dmabuf(s, &s->dma_dac1);
-       s->open_mode &= ~FMODE_DAC;
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_dac_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = es1370_write_dac,
-       .poll           = es1370_poll_dac,
-       .ioctl          = es1370_ioctl_dac,
-       .mmap           = es1370_mmap_dac,
-       .open           = es1370_open_dac,
-       .release        = es1370_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t es1370_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       es1370_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (s->dev_midi == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               outb(UCTRL_CNTRL_SWR, s->io+ES1370_REG_UART_CONTROL);
-               outb(0, s->io+ES1370_REG_UART_CONTROL);
-               outb(0, s->io+ES1370_REG_UART_TEST);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       s->ctrl |= CTRL_UART_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       es1370_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_midi_release(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) 
-                               break;
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");)
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->ctrl &= ~CTRL_UART_EN;
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1370_midi_read,
-       .write          = es1370_midi_write,
-       .poll           = es1370_midi_poll,
-       .open           = es1370_midi_open,
-       .release        = es1370_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int lineout[NR_DEVICE];
-static int micbias[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(lineout, bool, NULL, 0);
-MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-module_param_array(micbias, bool, NULL, 0);
-MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE3, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 },
-       { SOUND_MIXER_WRITE_OGAIN, 0x4040 }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1370_register_gameport(struct es1370_state *s)
-{
-       struct gameport *gp;
-
-       if (!request_region(0x200, JOY_EXTENT, "es1370")) {
-               printk(KERN_ERR "es1370: joystick io port 0x200 in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "es1370: can not allocate memory for gameport\n");
-               release_region(0x200, JOY_EXTENT);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "ESS1370");
-       gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-       gp->dev.parent = &s->dev->dev;
-       gp->io = 0x200;
-
-       s->ctrl |= CTRL_JYSTK_EN;
-       outl(s->ctrl, s->io + ES1370_REG_CONTROL);
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void es1370_unregister_gameport(struct es1370_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, JOY_EXTENT);
-
-       }
-}
-
-#else
-static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; }
-static inline void es1370_unregister_gameport(struct es1370_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct es1370_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-
-       if ( !(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-            !pci_resource_start(pcidev, 0)
-       )
-               return -ENODEV;
-       if (pcidev->irq == 0) 
-               return -ENODEV;
-       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-       if (i) {
-               printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
-               return i;
-       }
-       if (!(s = kmalloc(sizeof(struct es1370_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "es1370: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct es1370_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac1.wait);
-       init_waitqueue_head(&s->dma_dac2.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = ES1370_MAGIC;
-       s->dev = pcidev;
-       s->io = pci_resource_start(pcidev, 0);
-       s->irq = pcidev->irq;
-       if (!request_region(s->io, ES1370_EXTENT, "es1370")) {
-               printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
-               ret = -EBUSY;
-               goto err_region;
-       }
-       if ((ret=request_irq(s->irq, es1370_interrupt, IRQF_SHARED, "es1370",s))) {
-               printk(KERN_ERR "es1370: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-
-       /* initialize codec registers */
-       /* note: setting CTRL_SERR_DIS is reported to break
-        * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */
-       s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
-       if (lineout[devindex])
-               s->ctrl |= CTRL_XCTL0;
-       if (micbias[devindex])
-               s->ctrl |= CTRL_XCTL1;
-       s->sctrl = 0;
-       printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n",
-              s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in",
-              (s->ctrl & CTRL_XCTL1) ? "1" : "0");
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops, -1)) < 0) {
-               ret = s->dev_dac;
-               goto err_dev3;
-       }
-       if ((s->dev_midi = register_sound_midi(&es1370_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev4;
-       }
-       /* initialize the chips */
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       /* point phantom write channel to "bugbuf" */
-       s->bugbuf_cpu = pci_alloc_consistent(pcidev,16,&s->bugbuf_dma);
-       if (!s->bugbuf_cpu) {
-               ret = -ENOMEM;
-               goto err_dev5;
-       }
-       outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       outl(s->bugbuf_dma, s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff));
-       outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff));
-       pci_set_master(pcidev);  /* enable bus mastering */
-       wrcodec(s, 0x16, 3); /* no RST, PD */
-       wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!!  */
-       wrcodec(s, 0x18, 0); /* recording source is mixer */
-       wrcodec(s, 0x19, s->mix.micpreamp = 1); /* turn on MIC preamp */
-       s->mix.imix = 1;
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-
-       es1370_register_gameport(s);
-
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_dev5:
-       unregister_sound_midi(s->dev_midi);
- err_dev4:
-       unregister_sound_dsp(s->dev_dac);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "es1370: cannot register misc device\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->io, ES1370_EXTENT);
- err_region:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit es1370_remove(struct pci_dev *dev)
-{
-       struct es1370_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-       outl(CTRL_SERR_DIS | (1 << CTRL_SH_WTSRSEL), s->io+ES1370_REG_CONTROL); /* switch everything off */
-       outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       es1370_unregister_gameport(s);
-       release_region(s->io, ES1370_EXTENT);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_dsp(s->dev_dac);
-       unregister_sound_midi(s->dev_midi);
-       pci_free_consistent(dev, 16, s->bugbuf_cpu, s->bugbuf_dma);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1370_driver = {
-       .name           = "es1370",
-       .id_table       = id_table,
-       .probe          = es1370_probe,
-       .remove         = __devexit_p(es1370_remove),
-};
-
-static int __init init_es1370(void)
-{
-       printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&es1370_driver);
-}
-
-static void __exit cleanup_es1370(void)
-{
-       printk(KERN_INFO "es1370: unloading\n");
-       pci_unregister_driver(&es1370_driver);
-}
-
-module_init(init_es1370);
-module_exit(cleanup_es1370);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1370=lineout[,micbias]] */
-
-static int __init es1370_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-
-       (void)
-       ((get_option(&str,&lineout [nr_dev]) == 2)
-        && get_option(&str,&micbias [nr_dev])
-       );
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("es1370=", es1370_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
deleted file mode 100644 (file)
index 82f40a0..0000000
+++ /dev/null
@@ -1,2516 +0,0 @@
-/****************************************************************************/
-
-/*
- *      esssolo1.c  --  ESS Technology Solo1 (ES1946) audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Module command line parameters:
- *   none so far
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  Revision history
- *    10.11.1998   0.1   Initial release (without any hardware)
- *    22.03.1999   0.2   cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *                       return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.3   implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *    15.06.1999   0.4   Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.5   Add pci_set_master
- *    12.08.1999   0.6   Fix MIDI UART crashing the driver
- *                       Changed mixer semantics from OSS documented
- *                       behaviour to OSS "code behaviour".
- *                       Recording might actually work now.
- *                       The real DDMA controller address register is at PCI config
- *                       0x60, while the register at 0x18 is used as a placeholder
- *                       register for BIOS address allocation. This register
- *                       is supposed to be copied into 0x60, according
- *                       to the Solo1 datasheet. When I do that, I can access
- *                       the DDMA registers except the mask bit, which
- *                       is stuck at 1. When I copy the contents of 0x18 +0x10
- *                       to the DDMA base register, everything seems to work.
- *                       The fun part is that the Windows Solo1 driver doesn't
- *                       seem to do these tricks.
- *                       Bugs remaining: plops and clicks when starting/stopping playback
- *    31.08.1999   0.7   add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.8   change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    07.10.1999   0.9   Fix initialization; complain if sequencer writes time out
- *                       Revised resource grabbing for the FM synthesizer
- *    28.10.1999   0.10  More waitqueue races fixed
- *    09.12.1999   0.11  Work around stupid Alpha port issue (virt_to_bus(kmalloc(GFP_DMA)) > 16M)
- *                       Disabling recording on Alpha
- *    12.01.2000   0.12  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       Integrated (aka redid 8-)) APM support patch by Zach Brown
- *    07.02.2000   0.13  Use pci_alloc_consistent and pci_register_driver
- *    19.02.2000   0.14  Use pci_dma_supported to determine if recording should be disabled
- *    13.03.2000   0.15  Reintroduce initialization of a couple of PCI config space registers
- *    21.11.2000   0.16  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.17  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.18  Register/Unregister gameport, original patch from
- *                       Nathaniel Daw <daw@cs.cmu.edu>
- *                       Fix SETTRIGGER non OSS API conformity
- *    10.03.2001         provide abs function, prevent picking up a bogus kernel macro
- *                       for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
- *    15.05.2001         pci_enable_device moved, return values in probe cleaned
- *                       up. Marcus Meissner <mm@caldera.de>
- *    22.05.2001   0.19  more cleanups, changed PM to PCI 2.4 style, got rid
- *                       of global list of devices, using pci device data.
- *                       Marcus Meissner <mm@caldera.de>
- *    03.01.2003   0.20  open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS         0x125d
-#endif
-#ifndef PCI_DEVICE_ID_ESS_SOLO1
-#define PCI_DEVICE_ID_ESS_SOLO1   0x1969
-#endif
-
-#define SOLO1_MAGIC  ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1)
-
-#define DDMABASE_OFFSET           0    /* chip bug workaround kludge */
-#define DDMABASE_EXTENT           16
-
-#define IOBASE_EXTENT             16
-#define SBBASE_EXTENT             16
-#define VCBASE_EXTENT             (DDMABASE_EXTENT+DDMABASE_OFFSET)
-#define MPUBASE_EXTENT            4
-#define GPBASE_EXTENT             4
-#define GAMEPORT_EXTENT                  4
-
-#define FMSYNTH_EXTENT            4
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static struct pci_driver solo1_driver;
-
-/* --------------------------------------------------------------------- */
-
-struct solo1_state {
-       /* magic */
-       unsigned int magic;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-       int dev_dmfm;
-
-       /* hardware resources */
-       unsigned long iobase, sbbase, vcbase, ddmabase, mpubase; /* long for SPARC */
-       unsigned int irq;
-
-       /* mixer registers */
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-       } mix;
-
-       /* wave stuff */
-       unsigned fmt;
-       unsigned channels;
-       unsigned rate;
-       unsigned char clkdiv;
-       unsigned ena;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#if SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void write_seq(struct solo1_state *s, unsigned char data)
-{
-        int i;
-       unsigned long flags;
-
-       /* the local_irq_save stunt is to send the data within the command window */
-        for (i = 0; i < 0xffff; i++) {
-               local_irq_save(flags);
-                if (!(inb(s->sbbase+0xc) & 0x80)) {
-                        outb(data, s->sbbase+0xc);
-                       local_irq_restore(flags);
-                        return;
-                }
-               local_irq_restore(flags);
-       }
-       printk(KERN_ERR "esssolo1: write_seq timeout\n");
-       outb(data, s->sbbase+0xc);
-}
-
-static inline int read_seq(struct solo1_state *s, unsigned char *data)
-{
-        int i;
-
-        if (!data)
-                return 0;
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80) {
-                        *data = inb(s->sbbase+0xa);
-                        return 1;
-                }
-       printk(KERN_ERR "esssolo1: read_seq timeout\n");
-        return 0;
-}
-
-static inline int reset_ctrl(struct solo1_state *s)
-{
-        int i;
-
-        outb(3, s->sbbase+6); /* clear sequencer and FIFO */
-        udelay(10);
-        outb(0, s->sbbase+6);
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80)
-                        if (inb(s->sbbase+0xa) == 0xaa) {
-                               write_seq(s, 0xc6); /* enter enhanced mode */
-                                return 1;
-                       }
-        return 0;
-}
-
-static void write_ctrl(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-       write_seq(s, reg);
-       write_seq(s, data);
-}
-
-#if 0 /* unused */
-static unsigned char read_ctrl(struct solo1_state *s, unsigned char reg)
-{
-        unsigned char r;
-
-       write_seq(s, 0xc0);
-       write_seq(s, reg);
-       read_seq(s, &r);
-       return r;
-}
-#endif /* unused */
-
-static void write_mixer(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-       outb(reg, s->sbbase+4);
-       outb(data, s->sbbase+5);
-}
-
-static unsigned char read_mixer(struct solo1_state *s, unsigned char reg)
-{
-       outb(reg, s->sbbase+4);
-       return inb(s->sbbase+5);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_dac(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_WRITE;
-       write_mixer(s, 0x78, 0x10);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               s->ena |= FMODE_WRITE;
-               write_mixer(s, 0x78, 0x12);
-               udelay(10);
-               write_mixer(s, 0x78, 0x13);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_adc(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_READ;
-       write_ctrl(s, 0xb8, 0xe);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               s->ena |= FMODE_READ;
-               write_ctrl(s, 0xb8, 0xf);
-#if 0
-               printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf);
-               printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x  stat: 0x%02x\n", 
-                      inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8));
-#endif
-                outb(0, s->ddmabase+0xd); /* master reset */
-               outb(1, s->ddmabase+0xf);  /* mask */
-               outb(0x54/*0x14*/, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-               outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase);
-               outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-               outb(0, s->ddmabase+0xf);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-       printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x  SBstat: 0x%02x\n"
-              KERN_DEBUG "solo1: DMA: stat: 0x%02x  cnt: 0x%04x  mask: 0x%02x\n", 
-              read_ctrl(s, 0xb8), inb(s->sbbase+0xc), 
-              inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf));
-       printk(KERN_DEBUG "solo1: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"  
-              KERN_DEBUG "solo1: B1: 0x%02x  B2: 0x%02x  B4: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n",
-              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb4), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), 
-              read_ctrl(s, 0xb9));
-#endif
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-       int order;
-       unsigned bytespersec;
-       unsigned bufs, sample_shift = 0;
-       struct page *page, *pend;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-                for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               sample_shift++;
-       if (s->channels > 1)
-               sample_shift++;
-       bytespersec = s->rate << sample_shift;
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytespersec)
-                       db->fragshift = ld2(bytespersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytespersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift;
-       db->dmasize = db->numfrag << db->fragshift;
-       db->enabled = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct solo1_state *s)
-{
-       unsigned long va;
-       int c;
-
-       stop_adc(s);
-       /* check if PCI implementation supports 24bit busmaster DMA */
-       if (s->dev->dma_mask > 0xffffff)
-               return -EIO;
-       if ((c = prog_dmabuf(s, &s->dma_adc)))
-               return c;
-       va = s->dma_adc.dmaaddr;
-       if ((va & ~((1<<24)-1)))
-               panic("solo1: buffer above 16M boundary");
-       outb(0, s->ddmabase+0xd);  /* clear */
-       outb(1, s->ddmabase+0xf); /* mask */
-       /*outb(0, s->ddmabase+8);*/  /* enable (enable is active low!) */
-       outb(0x54, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-       outl(va, s->ddmabase);
-       outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-       c = - s->dma_adc.fragsamples;
-       write_ctrl(s, 0xa4, c);
-       write_ctrl(s, 0xa5, c >> 8);
-       outb(0, s->ddmabase+0xf);
-       s->dma_adc.ready = 1;
-       return 0;
-}
-
-static int prog_dmabuf_dac(struct solo1_state *s)
-{
-       unsigned long va;
-       int c;
-
-       stop_dac(s);
-       if ((c = prog_dmabuf(s, &s->dma_dac)))
-               return c;
-       memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80, s->dma_dac.dmasize); /* almost correct for U16 */
-       va = s->dma_dac.dmaaddr;
-       if ((va ^ (va + s->dma_dac.dmasize - 1)) & ~((1<<20)-1))
-               panic("solo1: buffer crosses 1M boundary");
-       outl(va, s->iobase);
-       /* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */
-       outw(s->dma_dac.dmasize, s->iobase+4);
-       c = - s->dma_dac.fragsamples;
-       write_mixer(s, 0x74, c);
-       write_mixer(s, 0x76, c >> 8);
-       outb(0xa, s->iobase+6);
-       s->dma_dac.ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *)buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-
-static void solo1_update_ptr(struct solo1_state *s)
-{
-       int diff;
-       unsigned hwptr;
-
-       /* update ADC pointer */
-       if (s->ena & FMODE_READ) {
-               hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize;
-                diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-                s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-#if 0
-               printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n",
-                      s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count);
-#endif
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               wake_up(&s->dma_adc.wait);
-               } else {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->ena &= ~FMODE_READ;
-                               write_ctrl(s, 0xb8, 0xe);
-                               s->dma_adc.error++;
-                       }
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
-               }
-       }
-       /* update DAC pointer */
-       if (s->ena & FMODE_WRITE) {
-                hwptr = (s->dma_dac.dmasize - inw(s->iobase+4)) % s->dma_dac.dmasize;
-                diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-                s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-#if 0
-               printk(KERN_DEBUG "solo1: wr: hwptr %u swptr %u dmasize %u count %u\n",
-                      s->dma_dac.hwptr, s->dma_dac.swptr, s->dma_dac.dmasize, s->dma_dac.count);
-#endif
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               s->ena &= ~FMODE_WRITE;
-                               write_mixer(s, 0x78, 0x12);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s->dma_dac.rawbuf, s->dma_dac.dmasize, s->dma_dac.swptr,
-                                             s->dma_dac.fragsize, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void prog_codec(struct solo1_state *s)
-{
-       unsigned long flags;
-       int fdiv, filter;
-       unsigned char c;
-
-       reset_ctrl(s);
-       write_seq(s, 0xd3);
-       /* program sampling rates */
-       filter = s->rate * 9 / 20; /* Set filter roll-off to 90% of rate/2 */
-       fdiv = 256 - 7160000 / (filter * 82);
-       spin_lock_irqsave(&s->lock, flags);
-       write_ctrl(s, 0xa1, s->clkdiv);
-       write_ctrl(s, 0xa2, fdiv);
-       write_mixer(s, 0x70, s->clkdiv);
-       write_mixer(s, 0x72, fdiv);
-       /* program ADC parameters */
-       write_ctrl(s, 0xb8, 0xe);
-       write_ctrl(s, 0xb9, /*0x1*/0);
-       write_ctrl(s, 0xa8, (s->channels > 1) ? 0x11 : 0x12);
-       c = 0xd0;
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               c |= 0x04;
-       if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-               c |= 0x20;
-       if (s->channels > 1)
-               c ^= 0x48;
-       write_ctrl(s, 0xb7, (c & 0x70) | 1);
-       write_ctrl(s, 0xb7, c);
-       write_ctrl(s, 0xb1, 0x50);
-       write_ctrl(s, 0xb2, 0x50);
-       /* program DAC parameters */
-       c = 0x40;
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               c |= 1;
-       if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-               c |= 4;
-       if (s->channels > 1)
-               c |= 2;
-       write_mixer(s, 0x7a, c);
-       write_mixer(s, 0x78, 0x10);
-       s->ena = 0;
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "solo1: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != SOLO1_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned int mixer_src[8] = {
-               SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME,
-               SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0
-       };
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM]     = 1,   /* voice */
-               [SOUND_MIXER_SYNTH]   = 2,   /* FM */
-               [SOUND_MIXER_CD]      = 3,   /* CD */
-               [SOUND_MIXER_LINE]    = 4,   /* Line */
-               [SOUND_MIXER_LINE1]   = 5,   /* AUX */
-               [SOUND_MIXER_MIC]     = 6,   /* Mic */
-               [SOUND_MIXER_LINE2]   = 7,   /* Mono in */
-               [SOUND_MIXER_SPEAKER] = 8,   /* Speaker */
-               [SOUND_MIXER_RECLEV]  = 9,   /* Recording level */
-               [SOUND_MIXER_VOLUME]  = 10   /* Master Volume */
-       };
-       static const unsigned char mixreg[] = {
-               0x7c,   /* voice */
-               0x36,   /* FM */
-               0x38,   /* CD */
-               0x3e,   /* Line */
-               0x3a,   /* AUX */
-               0x1a,   /* Mic */
-               0x6d    /* Mono in */
-       };
-       unsigned char l, r, rl, rr, vidx;
-       int i, val;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               /* enable/disable/query mixer preamp */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       val = val ? 0xff : 0xf7;
-                       write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
-               }
-               val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
-               return put_user(val, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               /* enable/disable/query spatializer */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       val &= 0x3f;
-                       write_mixer(s, 0x52, val);
-                       write_mixer(s, 0x50, val ? 0x08 : 0);
-               }
-               return put_user(read_mixer(s, 0x52), p);
-       }
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strncpy(info.id, "Solo1", sizeof(info.id));
-               strncpy(info.name, "ESS Solo1", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strncpy(info.id, "Solo1", sizeof(info.id));
-               strncpy(info.name, "ESS Solo1", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(mixer_src[read_mixer(s, 0x1c) & 7], p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-                                       SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV |
-                                       SOUND_MASK_SPEAKER, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, p);
-
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-                                       SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                                return -EINVAL;
-                       return put_user(s->mix.vol[vidx-1], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-#if 0
-               {
-                       static const unsigned char regs[] = {
-                               0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c
-                       };
-                       int i;
-                       
-                       for (i = 0; i < sizeof(regs); i++)
-                               printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n",
-                                      regs[i], read_mixer(s, regs[i]));
-                       printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n",
-                              0xb4, read_ctrl(s, 0xb4));
-               }
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-                i = hweight32(val);
-                if (i == 0)
-                        return 0;
-                else if (i > 1) 
-                        val &= ~mixer_src[read_mixer(s, 0x1c) & 7];
-               for (i = 0; i < 8; i++) {
-                       if (mixer_src[i] & val)
-                               break;
-               }
-               if (i > 7)
-                       return 0;
-               write_mixer(s, 0x1c, i);
-               return 0;
-
-       case SOUND_MIXER_VOLUME:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               if (l < 6) {
-                       rl = 0x40;
-                       l = 0;
-               } else {
-                       rl = (l * 2 - 11) / 3;
-                       l = (rl * 3 + 11) / 2;
-               }
-               if (r < 6) {
-                       rr = 0x40;
-                       r = 0;
-               } else {
-                       rr = (r * 2 - 11) / 3;
-                       r = (rr * 3 + 11) / 2;
-               }
-               write_mixer(s, 0x60, rl);
-               write_mixer(s, 0x62, rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[9] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[9] = val;
-#endif
-               return put_user(s->mix.vol[9], p);
-
-       case SOUND_MIXER_SPEAKER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               else if (l < 2)
-                       l = 2;
-               rl = (l - 2) / 14;
-               l = rl * 14 + 2;
-               write_mixer(s, 0x3c, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[7] = l * 0x101;
-#else
-                s->mix.vol[7] = val;
-#endif
-               return put_user(s->mix.vol[7], p);
-
-       case SOUND_MIXER_RECLEV:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = (val << 1) & 0x1fe;
-               if (l > 200)
-                       l = 200;
-               else if (l < 5)
-                       l = 5;
-               r = (val >> 7) & 0x1fe;
-               if (r > 200)
-                       r = 200;
-               else if (r < 5)
-                       r = 5;
-               rl = (l - 5) / 13;
-               rr = (r - 5) / 13;
-               r = (rl * 13 + 5) / 2;
-               l = (rr * 13 + 5) / 2;
-               write_ctrl(s, 0xb4, (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[8] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[8] = val;
-#endif
-               return put_user(s->mix.vol[8], p);
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = (val << 1) & 0x1fe;
-               if (l > 200)
-                       l = 200;
-               else if (l < 5)
-                       l = 5;
-               r = (val >> 7) & 0x1fe;
-               if (r > 200)
-                       r = 200;
-               else if (r < 5)
-                       r = 5;
-               rl = (l - 5) / 13;
-               rr = (r - 5) / 13;
-               r = (rl * 13 + 5) / 2;
-               l = (rr * 13 + 5) / 2;
-               write_mixer(s, mixreg[vidx-1], (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[vidx-1] = val;
-#endif
-               return put_user(s->mix.vol[vidx-1], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-               drvr = pci_dev_driver (pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_mixer == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct solo1_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations solo1_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = solo1_ioctl_mixdev,
-       .open           = solo1_open_mixdev,
-       .release        = solo1_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct solo1_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-       
-       if (s->dma_dac.mapped)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
-               if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->channels > 1)
-                       tmo >>= 1;
-                if (!schedule_timeout(tmo + 1))
-                        printk(KERN_DEBUG "solo1: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-#ifdef DEBUGREC
-               printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x  cnt: %u\n", 
-                      read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt);
-#endif
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-#ifdef DEBUGREC
-                       printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-                              KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-                              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-                              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-                              inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-                       if (inb(s->ddmabase+15) & 1)
-                               printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-#ifdef DEBUGREC
-                       printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-                              KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-                              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-                              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-                              inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-#ifdef DEBUGREC
-               printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x\n", 
-                      read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc));
-#endif
-       }
-       remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t solo1_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-#if 0
-       printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x  71: 0x%02x  72: 0x%02x  74: 0x%02x  76: 0x%02x  78: 0x%02x  7A: 0x%02x\n"
-              KERN_DEBUG "solo1_write: DMA: addr: 0x%08x  cnt: 0x%04x  stat: 0x%02x  SBstat: 0x%02x\n", 
-              read_mixer(s, 0x70), read_mixer(s, 0x71), read_mixer(s, 0x72), read_mixer(s, 0x74), read_mixer(s, 0x76),
-              read_mixer(s, 0x78), read_mixer(s, 0x7a), inl(s->iobase), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-       printk(KERN_DEBUG "solo1_write: reg 78: 0x%02x  reg 7A: 0x%02x  DMAcnt: 0x%04x  DMAstat: 0x%02x  SBstat: 0x%02x\n", 
-              read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-#endif
-       ret = 0;
-       add_wait_queue(&s->dma_dac.wait, &wait);        
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-       remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       solo1_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize > s->dma_dac.count)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-
-static int solo1_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else 
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret, count;
-        int div1, div2;
-        unsigned rate1, rate2;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               prog_codec(s);
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program sampling rates */
-                       if (val > 48000)
-                               val = 48000;
-                       if (val < 6300)
-                               val = 6300;
-                       div1 = (768000 + val / 2) / val;
-                       rate1 = (768000 + div1 / 2) / div1;
-                       div1 = -div1;
-                       div2 = (793800 + val / 2) / val;
-                       rate2 = (793800 + div2 / 2) / div2;
-                       div2 = (-div2) & 0x7f;
-                       if (abs(val - rate2) < abs(val - rate1)) {
-                               rate1 = rate2;
-                               div1 = div2;
-                       }
-                       s->rate = rate1;
-                       s->clkdiv = div1;
-                       prog_codec(s);
-               }
-               return put_user(s->rate, p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               stop_adc(s);
-               stop_dac(s);
-               s->dma_adc.ready = s->dma_dac.ready = 0;
-               /* program channels */
-               s->channels = val ? 2 : 1;
-               prog_codec(s);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program channels */
-                       s->channels = (val >= 2) ? 2 : 1;
-                       prog_codec(s);
-               }
-               return put_user(s->channels, p);
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program format */
-                       if (val != AFMT_S16_LE && val != AFMT_U16_LE && 
-                           val != AFMT_S8 && val != AFMT_U8)
-                               val = AFMT_U8;
-                       s->fmt = val;
-                       prog_codec(s);
-               }
-               return put_user(s->fmt, p);
-
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & s->ena & FMODE_READ)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & s->ena & FMODE_WRITE)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_adc(s);
-                               if (inb(s->ddmabase+15) & 1)
-                                       printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-               printk(KERN_DEBUG "esssolo1: GETOPTR: bytes %u blocks %u ptr %u, buforder %u numfrag %u fragshift %u\n"
-                      KERN_DEBUG "esssolo1: swptr %u count %u fragsize %u dmasize %u fragsamples %u\n",
-                      cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
-                      s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
-#endif
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac(s)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user(s->channels, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int solo1_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               outb(0, s->iobase+6);  /* disable DMA */
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               outb(1, s->ddmabase+0xf); /* mask DMA channel */
-               outb(0, s->ddmabase+0xd); /* DMA master clear */
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static int solo1_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-       
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       s->fmt = AFMT_U8;
-       s->channels = 1;
-       s->rate = 8000;
-       s->clkdiv = 96 | 0x80;
-       s->ena = 0;
-       s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-       s->dma_adc.enabled = 1;
-       s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-       s->dma_dac.enabled = 1;
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       prog_codec(s);
-       return nonseekable_open(inode, file);
-}
-
-static /*const*/ struct file_operations solo1_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = solo1_read,
-       .write          = solo1_write,
-       .poll           = solo1_poll,
-       .ioctl          = solo1_ioctl,
-       .mmap           = solo1_mmap,
-       .open           = solo1_open,
-       .release        = solo1_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* hold spinlock for the following! */
-static void solo1_handle_midi(struct solo1_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       if (!(s->mpubase))
-               return;
-       wake = 0;
-       while (!(inb(s->mpubase+1) & 0x80)) {
-               ch = inb(s->mpubase);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->mpubase);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-static irqreturn_t solo1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct solo1_state *s = (struct solo1_state *)dev_id;
-       unsigned int intsrc;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inb(s->iobase+7); /* get interrupt source(s) */
-       if (!intsrc)
-               return IRQ_NONE;
-       (void)inb(s->sbbase+0xe);  /* clear interrupt */
-       spin_lock(&s->lock);
-       /* clear audio interrupts first */
-       if (intsrc & 0x20)
-               write_mixer(s, 0x7a, read_mixer(s, 0x7a) & 0x7f);
-       solo1_update_ptr(s);
-       solo1_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-static void solo1_midi_timer(unsigned long data)
-{
-       struct solo1_state *s = (struct solo1_state *)data;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&s->lock, flags);
-       solo1_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies+1;
-       add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-       add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t solo1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       solo1_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_flags & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int solo1_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_midi == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               outb(0xff, s->mpubase+1); /* reset command */
-               outb(0x3f, s->mpubase+1); /* uart command */
-               if (!(inb(s->mpubase+1) & 0x80))
-                       inb(s->mpubase);
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               outb(0xb0, s->iobase + 7); /* enable A1, A2, MPU irq's */
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies+1;
-               s->midi.timer.data = (unsigned long)s;
-               s->midi.timer.function = solo1_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_midi_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG "solo1: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               outb(0x30, s->iobase + 7); /* enable A1, A2 irq's */
-               del_timer(&s->midi.timer);              
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations solo1_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = solo1_midi_read,
-       .write          = solo1_midi_write,
-       .poll           = solo1_midi_poll,
-       .open           = solo1_midi_open,
-       .release        = solo1_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned char op_offset[18] = {
-               0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-               0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-               0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-       };
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       struct dm_fm_voice v;
-       struct dm_fm_note n;
-       struct dm_fm_params p;
-       unsigned int io;
-       unsigned int regb;
-
-       switch (cmd) {          
-       case FM_IOCTL_RESET:
-               for (regb = 0xb0; regb < 0xb9; regb++) {
-                       outb(regb, s->sbbase);
-                       outb(0, s->sbbase+1);
-                       outb(regb, s->sbbase+2);
-                       outb(0, s->sbbase+3);
-               }
-               return 0;
-
-       case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-                       return -EFAULT;
-               if (n.voice >= 18)
-                       return -EINVAL;
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->sbbase+2;
-               } else {
-                       regb = n.voice;
-                       io = s->sbbase;
-               }
-               outb(0xa0 + regb, io);
-               outb(n.fnum & 0xff, io+1);
-               outb(0xb0 + regb, io);
-               outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-               return 0;
-
-       case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-                       return -EFAULT;
-               if (v.voice >= 18)
-                       return -EINVAL;
-               regb = op_offset[v.voice];
-               io = s->sbbase + ((v.op & 1) << 1);
-               outb(0x20 + regb, io);
-               outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-                    ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-               outb(0x40 + regb, io);
-               outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-               outb(0x60 + regb, io);
-               outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-               outb(0x80 + regb, io);
-               outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-               outb(0xe0 + regb, io);
-               outb(v.waveform & 0x7, io+1);
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->sbbase+2;
-               } else {
-                       regb = n.voice;
-                       io = s->sbbase;
-               }
-               outb(0xc0 + regb, io);
-               outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-                    (v.connection & 1), io+1);
-               return 0;
-               
-       case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void __user *)arg, sizeof(p)))
-                       return -EFAULT;
-               outb(0x08, s->sbbase);
-               outb((p.kbd_split & 1) << 6, s->sbbase+1);
-               outb(0xbd, s->sbbase);
-               outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-                    ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->sbbase+1);
-               return 0;
-
-       case FM_IOCTL_SET_OPL:
-               outb(4, s->sbbase+2);
-               outb(arg, s->sbbase+3);
-               return 0;
-
-       case FM_IOCTL_SET_MODE:
-               outb(5, s->sbbase+2);
-               outb(arg & 1, s->sbbase+3);
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int solo1_dmfm_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_dmfm == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DMFM) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
-               mutex_unlock(&s->open_mutex);
-               printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
-               return -EBUSY;
-       }
-       /* init the stuff */
-       outb(1, s->sbbase);
-       outb(0x20, s->sbbase+1); /* enable waveforms */
-       outb(4, s->sbbase+2);
-       outb(0, s->sbbase+3);  /* no 4op enabled */
-       outb(5, s->sbbase+2);
-       outb(1, s->sbbase+3);  /* enable OPL3 */
-       s->open_mode |= FMODE_DMFM;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_dmfm_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned int regb;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~FMODE_DMFM;
-       for (regb = 0xb0; regb < 0xb9; regb++) {
-               outb(regb, s->sbbase);
-               outb(0, s->sbbase+1);
-               outb(regb, s->sbbase+2);
-               outb(0, s->sbbase+3);
-       }
-       release_region(s->sbbase, FMSYNTH_EXTENT);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations solo1_dmfm_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = solo1_dmfm_ioctl,
-       .open           = solo1_dmfm_open,
-       .release        = solo1_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-       { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 }
-};
-
-static int setup_solo1(struct solo1_state *s)
-{
-       struct pci_dev *pcidev = s->dev;
-       mm_segment_t fs;
-       int i, val;
-
-       /* initialize DDMA base address */
-       printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
-       pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
-       /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */
-       pci_write_config_dword(pcidev, 0x50, 0);
-       /* disable legacy audio address decode */
-       pci_write_config_word(pcidev, 0x40, 0x907f);
-
-       /* initialize the chips */
-       if (!reset_ctrl(s)) {
-               printk(KERN_ERR "esssolo1: cannot reset controller\n");
-               return -1;
-       }
-       outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */
-       
-       /* initialize mixer regs */
-       write_mixer(s, 0x7f, 0); /* disable music digital recording */
-       write_mixer(s, 0x7d, 0x0c); /* enable mic preamp, MONO_OUT is 2nd DAC right channel */
-       write_mixer(s, 0x64, 0x45); /* volume control */
-       write_mixer(s, 0x48, 0x10); /* enable music DAC/ES6xx interface */
-       write_mixer(s, 0x50, 0);  /* disable spatializer */
-       write_mixer(s, 0x52, 0);
-       write_mixer(s, 0x14, 0);  /* DAC1 minimum volume */
-       write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */
-       outb(0, s->ddmabase+0xd); /* DMA master clear */
-       outb(1, s->ddmabase+0xf); /* mask channel */
-       /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */
-
-       pci_set_master(pcidev);  /* enable bus mastering */
-       
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       val = 1; /* enable mic preamp */
-       mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
-       set_fs(fs);
-       return 0;
-}
-
-static int
-solo1_suspend(struct pci_dev *pci_dev, pm_message_t state) {
-       struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-       if (!s)
-               return 1;
-       outb(0, s->iobase+6);
-       /* DMA master clear */
-       outb(0, s->ddmabase+0xd); 
-       /* reset sequencer and FIFO */
-       outb(3, s->sbbase+6); 
-       /* turn off DDMA controller address space */
-       pci_write_config_word(s->dev, 0x60, 0); 
-       return 0;
-}
-
-static int
-solo1_resume(struct pci_dev *pci_dev) {
-       struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-       if (!s)
-               return 1;
-       setup_solo1(s);
-       return 0;
-}
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, GAMEPORT_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: gameport io ports are in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "solo1: can not allocate memory for gameport\n");
-               release_region(io_port, GAMEPORT_EXTENT);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "ESS Solo1 Gameport");
-       gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void solo1_unregister_gameport(struct solo1_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, GAMEPORT_EXTENT);
-       }
-}
-#else
-static inline int solo1_register_gameport(struct solo1_state *s, int io_port) { return -ENOSYS; }
-static inline void solo1_unregister_gameport(struct solo1_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct solo1_state *s;
-       int gpio;
-       int ret;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 1) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 2) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 3) & IORESOURCE_IO))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-
-       /* Recording requires 24-bit DMA, so attempt to set dma mask
-        * to 24 bits first, then 32 bits (playback only) if that fails.
-        */
-       if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK) &&
-           pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
-               printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-
-       if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "solo1: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct solo1_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = SOLO1_MAGIC;
-       s->dev = pcidev;
-       s->iobase = pci_resource_start(pcidev, 0);
-       s->sbbase = pci_resource_start(pcidev, 1);
-       s->vcbase = pci_resource_start(pcidev, 2);
-       s->ddmabase = s->vcbase + DDMABASE_OFFSET;
-       s->mpubase = pci_resource_start(pcidev, 3);
-       gpio = pci_resource_start(pcidev, 4);
-       s->irq = pcidev->irq;
-       ret = -EBUSY;
-       if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region1;
-       }
-       if (!request_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region2;
-       }
-       if (!request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region3;
-       }
-       if (!request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region4;
-       }
-       if ((ret=request_irq(s->irq,solo1_interrupt,IRQF_SHARED,"ESS Solo1",s))) {
-               printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&solo1_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&solo1_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev3;
-       }
-       if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0) {
-               ret = s->dev_dmfm;
-               goto err_dev4;
-       }
-       if (setup_solo1(s)) {
-               ret = -EIO;
-               goto err;
-       }
-       /* register gameport */
-       solo1_register_gameport(s, gpio);
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       return 0;
-
- err:
-       unregister_sound_special(s->dev_dmfm);
- err_dev4:
-       unregister_sound_midi(s->dev_midi);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "solo1: initialisation error\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->mpubase, MPUBASE_EXTENT);
- err_region4:
-       release_region(s->ddmabase, DDMABASE_EXTENT);
- err_region3:
-       release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
- err_region2:
-       release_region(s->iobase, IOBASE_EXTENT);
- err_region1:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit solo1_remove(struct pci_dev *dev)
-{
-       struct solo1_state *s = pci_get_drvdata(dev);
-       
-       if (!s)
-               return;
-       /* stop DMA controller */
-       outb(0, s->iobase+6);
-       outb(0, s->ddmabase+0xd); /* DMA master clear */
-       outb(3, s->sbbase+6); /* reset sequencer and FIFO */
-       synchronize_irq(s->irq);
-       pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */
-       free_irq(s->irq, s);
-       solo1_unregister_gameport(s);
-       release_region(s->iobase, IOBASE_EXTENT);
-       release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
-       release_region(s->ddmabase, DDMABASE_EXTENT);
-       release_region(s->mpubase, MPUBASE_EXTENT);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       unregister_sound_special(s->dev_dmfm);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver solo1_driver = {
-       .name           = "ESS Solo1",
-       .id_table       = id_table,
-       .probe          = solo1_probe,
-       .remove         = __devexit_p(solo1_remove),
-       .suspend        = solo1_suspend,
-       .resume         = solo1_resume,
-};
-
-
-static int __init init_solo1(void)
-{
-       printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ESS Solo1 Driver");
-MODULE_LICENSE("GPL");
-
-
-static void __exit cleanup_solo1(void)
-{
-       printk(KERN_INFO "solo1: unloading\n");
-       pci_unregister_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-module_init(init_solo1);
-module_exit(cleanup_solo1);
-
diff --git a/sound/oss/forte.c b/sound/oss/forte.c
deleted file mode 100644 (file)
index ea1c020..0000000
+++ /dev/null
@@ -1,2139 +0,0 @@
-/*
- * forte.c - ForteMedia FM801 OSS Driver
- *
- * Written by Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2002 Hewlett-Packard Company
- * Portions Copyright (C) 2003 Martin K. Petersen
- *
- * Latest version: http://mkp.net/forte/
- *
- * Based upon the ALSA FM801 driver by Jaroslav Kysela and OSS drivers
- * by Thomas Sailer, Alan Cox, Zach Brown, and Jeff Garzik.  Thanks
- * guys!
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-
-#include <linux/delay.h>
-#include <linux/poll.h>
-
-#include <linux/sound.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-
-#include <linux/proc_fs.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#define DRIVER_NAME    "forte"
-#define DRIVER_VERSION         "$Id: forte.c,v 1.63 2003/03/01 05:32:42 mkp Exp $"
-#define PFX            DRIVER_NAME ": "
-
-#undef M_DEBUG
-
-#ifdef M_DEBUG
-#define DPRINTK(args...) printk(KERN_WARNING args)
-#else
-#define DPRINTK(args...)
-#endif
-
-/* Card capabilities */
-#define FORTE_CAPS              (DSP_CAP_MMAP | DSP_CAP_TRIGGER)
-
-/* Supported audio formats */
-#define FORTE_FMTS             (AFMT_U8 | AFMT_S16_LE)
-
-/* Buffers */
-#define FORTE_MIN_FRAG_SIZE     256
-#define FORTE_MAX_FRAG_SIZE     PAGE_SIZE
-#define FORTE_DEF_FRAG_SIZE     256
-#define FORTE_MIN_FRAGMENTS     2
-#define FORTE_MAX_FRAGMENTS     256
-#define FORTE_DEF_FRAGMENTS     2
-#define FORTE_MIN_BUF_MSECS     500
-#define FORTE_MAX_BUF_MSECS     1000
-
-/* PCI BARs */
-#define FORTE_PCM_VOL           0x00    /* PCM Output Volume */
-#define FORTE_FM_VOL            0x02    /* FM Output Volume */
-#define FORTE_I2S_VOL           0x04    /* I2S Volume */
-#define FORTE_REC_SRC           0x06    /* Record Source */
-#define FORTE_PLY_CTRL          0x08    /* Playback Control */
-#define FORTE_PLY_COUNT         0x0a    /* Playback Count */
-#define FORTE_PLY_BUF1          0x0c    /* Playback Buffer I */
-#define FORTE_PLY_BUF2          0x10    /* Playback Buffer II */
-#define FORTE_CAP_CTRL          0x14    /* Capture Control */
-#define FORTE_CAP_COUNT         0x16    /* Capture Count */
-#define FORTE_CAP_BUF1          0x18    /* Capture Buffer I */
-#define FORTE_CAP_BUF2          0x1c    /* Capture Buffer II */
-#define FORTE_CODEC_CTRL        0x22    /* Codec Control */
-#define FORTE_I2S_MODE          0x24    /* I2S Mode Control */
-#define FORTE_VOLUME            0x26    /* Volume Up/Down/Mute Status */
-#define FORTE_I2C_CTRL          0x29    /* I2C Control */
-#define FORTE_AC97_CMD          0x2a    /* AC'97 Command */
-#define FORTE_AC97_DATA         0x2c    /* AC'97 Data */
-#define FORTE_MPU401_DATA       0x30    /* MPU401 Data */
-#define FORTE_MPU401_CMD        0x31    /* MPU401 Command */
-#define FORTE_GPIO_CTRL         0x52    /* General Purpose I/O Control */
-#define FORTE_GEN_CTRL          0x54    /* General Control */
-#define FORTE_IRQ_MASK          0x56    /* Interrupt Mask */
-#define FORTE_IRQ_STATUS        0x5a    /* Interrupt Status */
-#define FORTE_OPL3_BANK0        0x68    /* OPL3 Status Read / Bank 0 Write */
-#define FORTE_OPL3_DATA0        0x69    /* OPL3 Data 0 Write */
-#define FORTE_OPL3_BANK1        0x6a    /* OPL3 Bank 1 Write */
-#define FORTE_OPL3_DATA1        0x6b    /* OPL3 Bank 1 Write */
-#define FORTE_POWERDOWN         0x70    /* Blocks Power Down Control */
-
-#define FORTE_CAP_OFFSET        FORTE_CAP_CTRL - FORTE_PLY_CTRL
-
-#define FORTE_AC97_ADDR_SHIFT   10
-
-/* Playback and record control register bits */
-#define FORTE_BUF1_LAST         (1<<1)
-#define FORTE_BUF2_LAST         (1<<2)
-#define FORTE_START             (1<<5)
-#define FORTE_PAUSE             (1<<6)
-#define FORTE_IMMED_STOP        (1<<7)
-#define FORTE_RATE_SHIFT        8
-#define FORTE_RATE_MASK         (15 << FORTE_RATE_SHIFT)
-#define FORTE_CHANNELS_4        (1<<12) /* Playback only */
-#define FORTE_CHANNELS_6        (2<<12) /* Playback only */
-#define FORTE_CHANNELS_6MS      (3<<12) /* Playback only */
-#define FORTE_CHANNELS_MASK     (3<<12)
-#define FORTE_16BIT             (1<<14)
-#define FORTE_STEREO            (1<<15)
-
-/* IRQ status bits */
-#define FORTE_IRQ_PLAYBACK      (1<<8)
-#define FORTE_IRQ_CAPTURE       (1<<9)
-#define FORTE_IRQ_VOLUME        (1<<14)
-#define FORTE_IRQ_MPU           (1<<15)
-
-/* CODEC control */
-#define FORTE_CC_CODEC_RESET    (1<<5)
-#define FORTE_CC_AC97_RESET     (1<<6)
-
-/* AC97 cmd */
-#define FORTE_AC97_WRITE        (0<<7)
-#define FORTE_AC97_READ         (1<<7)
-#define FORTE_AC97_DP_INVALID   (0<<8)
-#define FORTE_AC97_DP_VALID     (1<<8)
-#define FORTE_AC97_PORT_RDY     (0<<9)
-#define FORTE_AC97_PORT_BSY     (1<<9)
-
-
-struct forte_channel {
-        const char             *name;
-
-       unsigned short          ctrl;           /* Ctrl BAR contents */
-       unsigned long           iobase;         /* Ctrl BAR address */
-
-       wait_queue_head_t       wait;
-
-       void                    *buf;           /* Buffer */
-       dma_addr_t              buf_handle;     /* Buffer handle */
-
-        unsigned int           record;
-       unsigned int            format;
-        unsigned int           rate;
-       unsigned int            stereo;
-
-       unsigned int            frag_sz;        /* Current fragment size */
-       unsigned int            frag_num;       /* Current # of fragments */
-       unsigned int            frag_msecs;     /* Milliseconds per frag */
-       unsigned int            buf_sz;         /* Current buffer size */
-
-       unsigned int            hwptr;          /* Tail */
-       unsigned int            swptr;          /* Head */
-       unsigned int            filled_frags;   /* Fragments currently full */
-       unsigned int            next_buf;       /* Index of next buffer */
-
-       unsigned int            active;         /* Channel currently in use */
-       unsigned int            mapped;         /* mmap */
-
-       unsigned int            buf_pages;      /* Real size of buffer */
-       unsigned int            nr_irqs;        /* Number of interrupts */
-       unsigned int            bytes;          /* Total bytes */
-       unsigned int            residue;        /* Partial fragment */
-};
-
-
-struct forte_chip {
-       struct pci_dev          *pci_dev;
-       unsigned long           iobase;
-       int                     irq;
-
-       struct mutex            open_mutex;     /* Device access */
-       spinlock_t              lock;           /* State */
-
-       spinlock_t              ac97_lock;
-       struct ac97_codec       *ac97;
-
-       int                     multichannel;
-       int                     dsp;            /* OSS handle */
-       int                     trigger;        /* mmap I/O trigger */
-
-       struct forte_channel    play;
-       struct forte_channel    rec;
-};
-
-
-static int channels[] = { 2, 4, 6, };
-static int rates[]    = { 5500, 8000, 9600, 11025, 16000, 19200, 
-                         22050, 32000, 38400, 44100, 48000, };
-
-static struct forte_chip *forte;
-static int found;
-
-
-/* AC97 Codec -------------------------------------------------------------- */
-
-
-/** 
- * forte_ac97_wait:
- * @chip:      fm801 instance whose AC97 codec to wait on
- *
- * FIXME:
- *             Stop busy-waiting
- */
-
-static inline int
-forte_ac97_wait (struct forte_chip *chip)
-{
-       int i = 10000;
-
-       while ( (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_PORT_BSY) 
-               && i-- )
-               cpu_relax();
-
-       return i == 0;
-}
-
-
-/**
- * forte_ac97_read:
- * @codec:     AC97 codec to read from
- * @reg:       register to read
- */
-
-static u16
-forte_ac97_read (struct ac97_codec *codec, u8 reg)
-{
-       u16 ret = 0;
-       struct forte_chip *chip = codec->private_data;
-
-       spin_lock (&chip->ac97_lock);
-
-       /* Knock, knock */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_read: Serial bus busy\n");
-               goto out;
-       }
-
-       /* Send read command */
-       outw (reg | (1<<7), chip->iobase + FORTE_AC97_CMD);
-
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_read: Bus busy reading reg 0x%x\n",
-                       reg);
-               goto out;
-       }
-       
-       /* Sanity checking */
-       if (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_DP_INVALID) {
-               printk (KERN_ERR PFX "ac97_read: Invalid data port");
-               goto out;
-       }
-
-       /* Fetch result */
-       ret = inw (chip->iobase + FORTE_AC97_DATA);
-
- out:
-       spin_unlock (&chip->ac97_lock);
-       return ret;
-}
-
-
-/**
- * forte_ac97_write:
- * @codec:     AC97 codec to send command to
- * @reg:       register to write
- * @val:       value to write
- */
-
-static void
-forte_ac97_write (struct ac97_codec *codec, u8 reg, u16 val)
-{
-       struct forte_chip *chip = codec->private_data;
-
-       spin_lock (&chip->ac97_lock);
-
-       /* Knock, knock */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_write: Serial bus busy\n");
-               goto out;
-       }
-
-       outw (val, chip->iobase + FORTE_AC97_DATA);
-       outb (reg | FORTE_AC97_WRITE, chip->iobase + FORTE_AC97_CMD);
-
-       /* Wait for completion */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_write: Bus busy after write\n");
-               goto out;
-       }
-
- out:
-       spin_unlock (&chip->ac97_lock);
-}
-
-
-/* Mixer ------------------------------------------------------------------- */
-
-
-/**
- * forte_mixer_open:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_open (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = forte;
-       file->private_data = chip->ac97;
-       return 0;
-}
-
-
-/**
- * forte_mixer_release:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_release (struct inode *inode, struct file *file)
-{
-       /* We will welease Wodewick */
-       return 0;
-}
-
-
-/**
- * forte_mixer_ioctl:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_ioctl (struct inode *inode, struct file *file, 
-                  unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-
-       return codec->mixer_ioctl (codec, cmd, arg);
-}
-
-
-static struct file_operations forte_mixer_fops = {
-       .owner                  = THIS_MODULE,
-       .llseek                 = no_llseek,
-       .ioctl                  = forte_mixer_ioctl,
-       .open                   = forte_mixer_open,
-       .release                = forte_mixer_release,
-};
-
-
-/* Channel ----------------------------------------------------------------- */
-
-/** 
- * forte_channel_reset:
- * @channel:   Channel to reset
- * 
- * Locking:    Must be called with lock held.
- */
-
-static void
-forte_channel_reset (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase)
-               return;
-
-       DPRINTK ("%s: channel = %s\n", __FUNCTION__, channel->name);
-
-       channel->ctrl &= ~FORTE_START;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-       
-       /* We always play at least two fragments, hence these defaults */
-       channel->hwptr = channel->frag_sz;
-       channel->next_buf = 1;
-       channel->swptr = 0;
-       channel->filled_frags = 0;
-       channel->active = 0;
-       channel->bytes = 0;
-       channel->nr_irqs = 0;
-       channel->mapped = 0;
-       channel->residue = 0;
-}
-
-
-/** 
- * forte_channel_start:
- * @channel:   Channel to start (record/playback)
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_start (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase || channel->active) 
-               return;
-
-       channel->ctrl &= ~(FORTE_PAUSE | FORTE_BUF1_LAST | FORTE_BUF2_LAST
-                          | FORTE_IMMED_STOP);
-       channel->ctrl |= FORTE_START;
-       channel->active = 1;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_stop:
- * @channel:   Channel to stop
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_stop (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase) 
-               return;
-
-       channel->ctrl &= ~(FORTE_START | FORTE_PAUSE);  
-       channel->ctrl |= FORTE_IMMED_STOP;
-
-       channel->active = 0;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_pause:
- * @channel:   Channel to pause
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_pause (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase) 
-               return;
-
-       channel->ctrl |= FORTE_PAUSE;
-
-       channel->active = 0;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_rate:
- * @channel:   Channel whose rate to set.  Playback and record are
- *             independent.
- * @rate:      Channel rate in Hz
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_rate (struct forte_channel *channel, unsigned int rate)
-{
-       int new_rate;
-
-       if (!channel || !channel->iobase) 
-               return -EINVAL;
-
-       /* The FM801 only supports a handful of fixed frequencies.
-        * We find the value closest to what userland requested.
-        */
-       if      (rate <= 6250)  { rate = 5500;  new_rate =  0; }
-       else if (rate <= 8800)  { rate = 8000;  new_rate =  1; }
-       else if (rate <= 10312) { rate = 9600;  new_rate =  2; }
-       else if (rate <= 13512) { rate = 11025; new_rate =  3; }
-       else if (rate <= 17600) { rate = 16000; new_rate =  4; }
-       else if (rate <= 20625) { rate = 19200; new_rate =  5; }
-       else if (rate <= 27025) { rate = 22050; new_rate =  6; }
-       else if (rate <= 35200) { rate = 32000; new_rate =  7; }
-       else if (rate <= 41250) { rate = 38400; new_rate =  8; }
-       else if (rate <= 46050) { rate = 44100; new_rate =  9; }
-       else                    { rate = 48000; new_rate = 10; }
-
-       channel->ctrl &= ~FORTE_RATE_MASK;
-       channel->ctrl |= new_rate << FORTE_RATE_SHIFT;
-       channel->rate = rate;
-
-       DPRINTK ("%s: %s rate = %d\n", __FUNCTION__, channel->name, rate);
-
-       return rate;
-}
-
-
-/** 
- * forte_channel_format:
- * @channel:   Channel whose audio format to set
- * @format:    OSS format ID
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_format (struct forte_channel *channel, int format)
-{
-       if (!channel || !channel->iobase) 
-               return -EINVAL;
-
-       switch (format) {
-
-       case AFMT_QUERY:
-               break;
-       
-       case AFMT_U8:
-               channel->ctrl &= ~FORTE_16BIT;
-               channel->format = AFMT_U8;
-               break;
-
-       case AFMT_S16_LE:
-       default:
-               channel->ctrl |= FORTE_16BIT;
-               channel->format = AFMT_S16_LE;
-               break;
-       }
-
-       DPRINTK ("%s: %s want %d format, got %d\n", __FUNCTION__, channel->name, 
-                format, channel->format);
-
-       return channel->format;
-}
-
-
-/** 
- * forte_channel_stereo:
- * @channel:   Channel to toggle
- * @stereo:    0 for Mono, 1 for Stereo
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_stereo (struct forte_channel *channel, unsigned int stereo)
-{
-       int ret;
-
-       if (!channel || !channel->iobase)
-               return -EINVAL;
-
-       DPRINTK ("%s: %s stereo = %d\n", __FUNCTION__, channel->name, stereo);
-
-       switch (stereo) {
-
-       case 0:
-               channel->ctrl &= ~(FORTE_STEREO | FORTE_CHANNELS_MASK);
-               channel-> stereo = stereo;
-               ret = stereo;
-               break;
-
-       case 1:
-               channel->ctrl &= ~FORTE_CHANNELS_MASK;
-               channel->ctrl |= FORTE_STEREO;
-               channel-> stereo = stereo;
-               ret = stereo;
-               break;
-
-       default:
-               DPRINTK ("Unsupported channel format");
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-
-/** 
- * forte_channel_buffer:
- * @channel:   Channel whose buffer to set up
- *
- * Locking:    Must be called with lock held.
- */
-
-static void
-forte_channel_buffer (struct forte_channel *channel, int sz, int num)
-{
-       unsigned int msecs, shift;
-
-       /* Go away, I'm busy */
-       if (channel->filled_frags || channel->bytes)
-               return;
-
-       /* Fragment size must be a power of 2 */
-       shift = 0; sz++;
-       while (sz >>= 1)
-               shift++;
-       channel->frag_sz = 1 << shift;
-
-       /* Round fragment size to something reasonable */
-       if (channel->frag_sz < FORTE_MIN_FRAG_SIZE)
-               channel->frag_sz = FORTE_MIN_FRAG_SIZE;
-
-       if (channel->frag_sz > FORTE_MAX_FRAG_SIZE)
-               channel->frag_sz = FORTE_MAX_FRAG_SIZE;
-
-       /* Find fragment length in milliseconds */
-       msecs = channel->frag_sz /
-               (channel->format == AFMT_S16_LE ? 2 : 1) /
-               (channel->stereo ? 2 : 1) /
-               (channel->rate / 1000);
-
-       channel->frag_msecs = msecs;
-
-       /* Pick a suitable number of fragments */
-       if (msecs * num < FORTE_MIN_BUF_MSECS)
-            num = FORTE_MIN_BUF_MSECS / msecs;
-
-       if (msecs * num > FORTE_MAX_BUF_MSECS)
-            num = FORTE_MAX_BUF_MSECS / msecs;
-
-       /* Fragment number must be a power of 2 */
-       shift = 0;      
-       while (num >>= 1)
-               shift++;
-       channel->frag_num = 1 << (shift + 1);
-
-       /* Round fragment number to something reasonable */
-       if (channel->frag_num < FORTE_MIN_FRAGMENTS)
-               channel->frag_num = FORTE_MIN_FRAGMENTS;
-
-       if (channel->frag_num > FORTE_MAX_FRAGMENTS)
-               channel->frag_num = FORTE_MAX_FRAGMENTS;
-
-       channel->buf_sz = channel->frag_sz * channel->frag_num;
-
-       DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d\n",
-                __FUNCTION__, channel->name, channel->frag_sz, 
-                channel->frag_num, channel->buf_sz);
-}
-
-
-/** 
- * forte_channel_prep:
- * @channel:   Channel whose buffer to prepare
- *
- * Locking:    Lock held.
- */
-
-static void
-forte_channel_prep (struct forte_channel *channel)
-{
-       struct page *page;
-       int i;
-       
-       if (channel->buf)
-               return;
-
-       forte_channel_buffer (channel, channel->frag_sz, channel->frag_num);
-       channel->buf_pages = channel->buf_sz >> PAGE_SHIFT;
-
-       if (channel->buf_sz % PAGE_SIZE)
-               channel->buf_pages++;
-
-       DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d, pg = %d\n", 
-                __FUNCTION__, channel->name, channel->frag_sz, 
-                channel->frag_num, channel->buf_sz, channel->buf_pages);
-
-       /* DMA buffer */
-       channel->buf = pci_alloc_consistent (forte->pci_dev, 
-                                            channel->buf_pages * PAGE_SIZE,
-                                            &channel->buf_handle);
-
-       if (!channel->buf || !channel->buf_handle)
-               BUG();
-
-       page = virt_to_page (channel->buf);
-       
-       /* FIXME: can this go away ? */
-       for (i = 0 ; i < channel->buf_pages ; i++)
-               SetPageReserved(page++);
-
-       /* Prep buffer registers */
-       outw (channel->frag_sz - 1, channel->iobase + FORTE_PLY_COUNT);
-       outl (channel->buf_handle, channel->iobase + FORTE_PLY_BUF1);
-       outl (channel->buf_handle + channel->frag_sz, 
-             channel->iobase + FORTE_PLY_BUF2);
-
-       /* Reset hwptr */
-       channel->hwptr = channel->frag_sz;
-       channel->next_buf = 1;
-
-       DPRINTK ("%s: %s buffer @ %p (%p)\n", __FUNCTION__, channel->name, 
-                channel->buf, channel->buf_handle);
-}
-
-
-/** 
- * forte_channel_drain:
- * @chip:      
- * @channel:   
- *
- * Locking:    Don't hold the lock.
- */
-
-static inline int
-forte_channel_drain (struct forte_channel *channel)
-{
-       DECLARE_WAITQUEUE (wait, current);
-       unsigned long flags;
-
-       DPRINTK ("%s\n", __FUNCTION__);
-
-       if (channel->mapped) {
-               spin_lock_irqsave (&forte->lock, flags);
-               forte_channel_stop (channel);
-               spin_unlock_irqrestore (&forte->lock, flags);
-               return 0;
-       }
-
-       spin_lock_irqsave (&forte->lock, flags);
-       add_wait_queue (&channel->wait, &wait);
-
-       for (;;) {
-               if (channel->active == 0 || channel->filled_frags == 1)
-                       break;
-
-               spin_unlock_irqrestore (&forte->lock, flags);
-
-               __set_current_state (TASK_INTERRUPTIBLE);
-               schedule();
-
-               spin_lock_irqsave (&forte->lock, flags);
-       }
-
-       forte_channel_stop (channel);
-       forte_channel_reset (channel);
-       set_current_state (TASK_RUNNING);
-       remove_wait_queue (&channel->wait, &wait);
-       spin_unlock_irqrestore (&forte->lock, flags);
-
-       return 0;
-}
-
-
-/** 
- * forte_channel_init:
- * @chip:      Forte chip instance the channel hangs off
- * @channel:   Channel to initialize
- *
- * Description:
- *             Initializes a channel, sets defaults, and allocates
- *             buffers.
- *
- * Locking:    No lock held.
- */
-
-static int
-forte_channel_init (struct forte_chip *chip, struct forte_channel *channel)
-{
-       DPRINTK ("%s: chip iobase @ %p\n", __FUNCTION__, (void *)chip->iobase);
-
-       spin_lock_irq (&chip->lock);
-       memset (channel, 0x0, sizeof (*channel));
-
-       if (channel == &chip->play) {
-               channel->name = "PCM_OUT";
-               channel->iobase = chip->iobase;
-               DPRINTK ("%s: PCM-OUT iobase @ %p\n", __FUNCTION__,
-                        (void *) channel->iobase);
-       }
-       else if (channel == &chip->rec) {
-               channel->name = "PCM_IN";
-               channel->iobase = chip->iobase + FORTE_CAP_OFFSET;
-               channel->record = 1;
-               DPRINTK ("%s: PCM-IN iobase @ %p\n", __FUNCTION__, 
-                        (void *) channel->iobase);
-       }
-       else
-               BUG();
-
-       init_waitqueue_head (&channel->wait);
-
-       /* Defaults: 48kHz, 16-bit, stereo */
-       channel->ctrl = inw (channel->iobase + FORTE_PLY_CTRL);
-       forte_channel_reset (channel);
-       forte_channel_stereo (channel, 1);
-       forte_channel_format (channel, AFMT_S16_LE);
-       forte_channel_rate (channel, 48000);
-       channel->frag_sz = FORTE_DEF_FRAG_SIZE;
-       channel->frag_num = FORTE_DEF_FRAGMENTS;
-
-       chip->trigger = 0;
-       spin_unlock_irq (&chip->lock);
-
-       return 0;
-}
-
-
-/** 
- * forte_channel_free:
- * @chip:      Chip this channel hangs off
- * @channel:   Channel to nuke 
- *
- * Description:
- *             Resets channel and frees buffers.
- *
- * Locking:    Hold your horses.
- */
-
-static void
-forte_channel_free (struct forte_chip *chip, struct forte_channel *channel)
-{
-       DPRINTK ("%s: %s\n", __FUNCTION__, channel->name);
-
-       if (!channel->buf_handle)
-               return;
-
-       pci_free_consistent (chip->pci_dev, channel->buf_pages * PAGE_SIZE, 
-                            channel->buf, channel->buf_handle);
-       
-       memset (channel, 0x0, sizeof (*channel));
-}
-
-
-/* DSP --------------------------------------------------------------------- */
-
-
-/**
- * forte_dsp_ioctl:
- */
-
-static int
-forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-                unsigned long arg)
-{
-       int ival=0, ret, rval=0, rd, wr, count;
-       struct forte_chip *chip;
-       struct audio_buf_info abi;
-       struct count_info cinfo;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       chip = file->private_data;
-       
-       if (file->f_mode & FMODE_WRITE)
-               wr = 1;
-       else 
-               wr = 0;
-
-       if (file->f_mode & FMODE_READ)
-               rd = 1;
-       else
-               rd = 0;
-
-       switch (cmd) {
-
-       case OSS_GETVERSION:
-               return put_user (SOUND_VERSION, p);
-
-       case SNDCTL_DSP_GETCAPS:
-               DPRINTK ("%s: GETCAPS\n", __FUNCTION__);
-
-               ival = FORTE_CAPS; /* DUPLEX */
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_GETFMTS:
-               DPRINTK ("%s: GETFMTS\n", __FUNCTION__);
-
-               ival = FORTE_FMTS; /* U8, 16LE */
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_SETFMT: /* U8, 16LE */
-               DPRINTK ("%s: SETFMT\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_format (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_format (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-       
-               return put_user (rval, p);
-
-       case SNDCTL_DSP_STEREO: /* 0 - mono, 1 - stereo */
-               DPRINTK ("%s: STEREO\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-       case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */
-               DPRINTK ("%s: CHANNELS\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->rec, ival-1) + 1;
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->play);
-                       rval = forte_channel_stereo (&chip->play, ival-1) + 1;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-       case SNDCTL_DSP_SPEED:
-               DPRINTK ("%s: SPEED\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                        return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_rate (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->play);
-                       rval = forte_channel_rate (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user(rval, p);
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__);
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd)
-                       ival = chip->rec.frag_sz;
-
-               if (wr)
-                       ival = chip->play.frag_sz;
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (ival, p);
-
-       case SNDCTL_DSP_RESET:
-               DPRINTK ("%s: RESET\n", __FUNCTION__);
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd)
-                       forte_channel_reset (&chip->rec);
-
-               if (wr)
-                       forte_channel_reset (&chip->play);
-
-               spin_unlock_irq (&chip->lock);
-
-                return 0;
-
-       case SNDCTL_DSP_SYNC:
-               DPRINTK ("%s: SYNC\n", __FUNCTION__);
-
-               if (wr)
-                       ret = forte_channel_drain (&chip->play);
-
-               return 0;
-
-       case SNDCTL_DSP_POST:
-               DPRINTK ("%s: POST\n", __FUNCTION__);
-
-               if (wr) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (chip->play.filled_frags)
-                               forte_channel_start (&chip->play);
-
-                       spin_unlock_irq (&chip->lock);
-               }
-
-                return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_buffer (&chip->rec, ival & 0xffff, 
-                                             (ival >> 16) & 0xffff);
-                       ival = (chip->rec.frag_num << 16) + chip->rec.frag_sz;
-               }
-
-               if (wr) {
-                       forte_channel_buffer (&chip->play, ival & 0xffff, 
-                                             (ival >> 16) & 0xffff);
-                       ival = (chip->play.frag_num << 16) +chip->play.frag_sz;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return put_user (ival, p);
-                
-        case SNDCTL_DSP_GETISPACE:
-               DPRINTK ("%s: GETISPACE\n", __FUNCTION__);
-
-               if (!rd)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               abi.fragstotal = chip->rec.frag_num;
-               abi.fragsize = chip->rec.frag_sz;
-                       
-               if (chip->rec.mapped) {
-                       abi.fragments = chip->rec.frag_num - 2;
-                       abi.bytes = abi.fragments * abi.fragsize;
-               }
-               else {
-                       abi.fragments = chip->rec.filled_frags;
-                       abi.bytes = abi.fragments * abi.fragsize;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETIPTR:
-               DPRINTK ("%s: GETIPTR\n", __FUNCTION__);
-
-               if (!rd)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (chip->rec.active) 
-                       cinfo.ptr = chip->rec.hwptr;
-               else
-                       cinfo.ptr = 0;
-
-               cinfo.bytes = chip->rec.bytes;
-               cinfo.blocks = chip->rec.nr_irqs;
-               chip->rec.nr_irqs = 0;
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOSPACE:
-               if (!wr)
-                       return -EINVAL;
-               
-               spin_lock_irq (&chip->lock);
-
-               abi.fragstotal = chip->play.frag_num;
-               abi.fragsize = chip->play.frag_sz;
-
-               if (chip->play.mapped) {
-                       abi.fragments = chip->play.frag_num - 2;
-                       abi.bytes = chip->play.buf_sz;
-               }
-               else {
-                       abi.fragments = chip->play.frag_num - 
-                               chip->play.filled_frags;
-
-                       if (chip->play.residue)
-                               abi.fragments--;
-
-                       abi.bytes = abi.fragments * abi.fragsize +
-                               chip->play.residue;
-               }
-
-               spin_unlock_irq (&chip->lock);
-               
-               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!wr)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (chip->play.active) 
-                       cinfo.ptr = chip->play.hwptr;
-               else
-                       cinfo.ptr = 0;
-
-               cinfo.bytes = chip->play.bytes;
-               cinfo.blocks = chip->play.nr_irqs;
-               chip->play.nr_irqs = 0;
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!wr)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (!chip->play.active) {
-                       ival = 0;
-               }
-               else if (chip->play.mapped) {
-                       count = inw (chip->play.iobase + FORTE_PLY_COUNT) + 1;
-                       ival = chip->play.frag_sz - count;
-               }
-               else {
-                       ival = chip->play.filled_frags * chip->play.frag_sz;
-
-                       if (chip->play.residue)
-                               ival += chip->play.frag_sz - chip->play.residue;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_SETDUPLEX:
-               DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__);
-
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__);
-               
-               return put_user (chip->trigger, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival);
-
-               if (wr) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (ival & PCM_ENABLE_OUTPUT)
-                               forte_channel_start (&chip->play);
-                       else {          
-                               chip->trigger = 1;
-                               forte_channel_prep (&chip->play);
-                               forte_channel_stop (&chip->play);
-                       }
-
-                       spin_unlock_irq (&chip->lock);
-               }
-               else if (rd) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (ival & PCM_ENABLE_INPUT)
-                               forte_channel_start (&chip->rec);
-                       else {          
-                               chip->trigger = 1;
-                               forte_channel_prep (&chip->rec);
-                               forte_channel_stop (&chip->rec);
-                       }
-
-                       spin_unlock_irq (&chip->lock);
-               }
-
-               return 0;
-               
-       case SOUND_PCM_READ_RATE:
-               DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__);          
-               return put_user (chip->play.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__);
-               return put_user (chip->play.stereo, p);
-
-       case SOUND_PCM_READ_BITS:
-               DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__);          
-               return put_user (chip->play.format, p);
-
-       case SNDCTL_DSP_NONBLOCK:
-               DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__);           
-                file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       default:
-               DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp);
-               break;
-       }
-
-       return -EINVAL;
-}
-
-
-/**
- * forte_dsp_open:
- */
-
-static int 
-forte_dsp_open (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */
-
-       if (file->f_flags & O_NONBLOCK) {
-               if (!mutex_trylock(&chip->open_mutex)) {
-                       DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__);
-                       return -EAGAIN;
-               }
-       }
-       else {
-               if (mutex_lock_interruptible(&chip->open_mutex)) {
-                       DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__);
-                       return -ERESTARTSYS;
-               }
-       }
-
-       file->private_data = forte;
-
-       DPRINTK ("%s: dsp opened by %d\n", __FUNCTION__, current->pid);
-
-       if (file->f_mode & FMODE_WRITE)
-               forte_channel_init (forte, &forte->play);
-
-       if (file->f_mode & FMODE_READ)
-               forte_channel_init (forte, &forte->rec);
-
-       return nonseekable_open(inode, file);
-}
-
-
-/**
- * forte_dsp_release:
- */
-
-static int 
-forte_dsp_release (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = file->private_data;
-       int ret = 0;
-
-       DPRINTK ("%s: chip @ %p\n", __FUNCTION__, chip);
-
-       if (file->f_mode & FMODE_WRITE) {
-               forte_channel_drain (&chip->play);
-
-               spin_lock_irq (&chip->lock);
-
-               forte_channel_free (chip, &chip->play);
-
-               spin_unlock_irq (&chip->lock);
-        }
-
-       if (file->f_mode & FMODE_READ) {
-               while (chip->rec.filled_frags > 0)
-                       interruptible_sleep_on (&chip->rec.wait);
-
-               spin_lock_irq (&chip->lock);
-
-               forte_channel_stop (&chip->rec);
-               forte_channel_free (chip, &chip->rec);
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       mutex_unlock(&chip->open_mutex);
-
-       return ret;
-}
-
-
-/**
- * forte_dsp_poll:
- *
- */
-
-static unsigned int 
-forte_dsp_poll (struct file *file, struct poll_table_struct *wait)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int mask = 0;
-
-       chip = file->private_data;
-
-       if (file->f_mode & FMODE_WRITE) {
-               channel = &chip->play;
-
-               if (channel->active)
-                       poll_wait (file, &channel->wait, wait);
-
-               spin_lock_irq (&chip->lock);
-
-               if (channel->frag_num - channel->filled_frags > 0)
-                       mask |= POLLOUT | POLLWRNORM;
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       if (file->f_mode & FMODE_READ) {
-               channel = &chip->rec;
-
-               if (channel->active)
-                       poll_wait (file, &channel->wait, wait);
-
-               spin_lock_irq (&chip->lock);
-
-               if (channel->filled_frags > 0)
-                       mask |= POLLIN | POLLRDNORM;
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       return mask;
-}
-
-
-/**
- * forte_dsp_mmap:
- */
-
-static int
-forte_dsp_mmap (struct file *file, struct vm_area_struct *vma)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned long size;
-       int ret;
-
-       chip = file->private_data;
-
-       DPRINTK ("%s: start %lXh, size %ld, pgoff %ld\n", __FUNCTION__,
-                 vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_pgoff);
-
-       spin_lock_irq (&chip->lock);
-
-       if (vma->vm_flags & VM_WRITE && chip->play.active) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-        if (vma->vm_flags & VM_READ && chip->rec.active) {
-               ret = -EBUSY;
-               goto out;
-        }
-
-       if (file->f_mode & FMODE_WRITE)
-               channel = &chip->play;
-       else if (file->f_mode & FMODE_READ)
-               channel = &chip->rec;
-       else {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       forte_channel_prep (channel);
-       channel->mapped = 1;
-
-        if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-                goto out;
-       }
-
-        size = vma->vm_end - vma->vm_start;
-
-        if (size > channel->buf_pages * PAGE_SIZE) {
-               DPRINTK ("%s: size (%ld) > buf_sz (%d) \n", __FUNCTION__,
-                        size, channel->buf_sz);
-               ret = -EINVAL;
-                goto out;
-       }
-
-        if (remap_pfn_range(vma, vma->vm_start,
-                             virt_to_phys(channel->buf) >> PAGE_SHIFT,
-                             size, vma->vm_page_prot)) {
-               DPRINTK ("%s: remap el a no worko\n", __FUNCTION__);
-               ret = -EAGAIN;
-                goto out;
-       }
-
-        ret = 0;
-
- out:
-       spin_unlock_irq (&chip->lock);
-        return ret;
-}
-
-
-/**
- * forte_dsp_write:
- */
-
-static ssize_t 
-forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes, 
-                loff_t *ppos)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int i = bytes, sz = 0;
-       unsigned long flags;
-
-       if (!access_ok (VERIFY_READ, buffer, bytes))
-               return -EFAULT;
-
-       chip = (struct forte_chip *) file->private_data;
-
-       if (!chip)
-               BUG();
-
-       channel = &chip->play;
-
-       if (!channel)
-               BUG();
-
-       spin_lock_irqsave (&chip->lock, flags);
-
-       /* Set up buffers with the right fragment size */
-       forte_channel_prep (channel);
-
-       while (i) {
-               /* All fragment buffers in use -> wait */
-               if (channel->frag_num - channel->filled_frags == 0) {
-                       DECLARE_WAITQUEUE (wait, current);
-
-                       /* For trigger or non-blocking operation, get out */
-                       if (chip->trigger || file->f_flags & O_NONBLOCK) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -EAGAIN;
-                       }
-
-                       /* Otherwise wait for buffers */
-                       add_wait_queue (&channel->wait, &wait);
-
-                       for (;;) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-
-                               set_current_state (TASK_INTERRUPTIBLE);
-                               schedule();
-
-                               spin_lock_irqsave (&chip->lock, flags);
-
-                               if (channel->frag_num - channel->filled_frags)
-                                       break;
-                       }
-
-                       remove_wait_queue (&channel->wait, &wait);
-                       set_current_state (TASK_RUNNING);
-
-                       if (signal_pending (current)) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -ERESTARTSYS;
-                       }
-               }
-
-               if (channel->residue)
-                       sz = channel->residue;
-               else if (i > channel->frag_sz)
-                       sz = channel->frag_sz;
-               else
-                       sz = i;
-
-               spin_unlock_irqrestore (&chip->lock, flags);
-
-               if (copy_from_user ((void *) channel->buf + channel->swptr, buffer, sz))
-                       return -EFAULT;
-
-               spin_lock_irqsave (&chip->lock, flags);
-
-               /* Advance software pointer */
-               buffer += sz;
-               channel->swptr += sz;
-               channel->swptr %= channel->buf_sz;
-               i -= sz;
-
-               /* Only bump filled_frags if a full fragment has been written */
-               if (channel->swptr % channel->frag_sz == 0) {
-                       channel->filled_frags++;
-                       channel->residue = 0;
-               }
-               else
-                       channel->residue = channel->frag_sz - sz;
-
-               /* If playback isn't active, start it */
-               if (channel->active == 0 && chip->trigger == 0)
-                       forte_channel_start (channel);
-       }
-
-       spin_unlock_irqrestore (&chip->lock, flags);
-
-       return bytes - i;
-}
-
-
-/**
- * forte_dsp_read:
- */
-
-static ssize_t 
-forte_dsp_read (struct file *file, char __user *buffer, size_t bytes, 
-               loff_t *ppos)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int i = bytes, sz;
-       unsigned long flags;
-
-       if (!access_ok (VERIFY_WRITE, buffer, bytes))
-               return -EFAULT;
-
-       chip = (struct forte_chip *) file->private_data;
-
-       if (!chip)
-               BUG();
-
-       channel = &chip->rec;
-
-       if (!channel)
-               BUG();
-
-       spin_lock_irqsave (&chip->lock, flags);
-
-       /* Set up buffers with the right fragment size */
-       forte_channel_prep (channel);
-
-       /* Start recording */
-       if (!chip->trigger)
-               forte_channel_start (channel);
-
-       while (i) {
-               /* No fragment buffers in use -> wait */
-               if (channel->filled_frags == 0) {
-                       DECLARE_WAITQUEUE (wait, current);
-
-                       /* For trigger mode operation, get out */
-                       if (chip->trigger) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -EAGAIN;
-                       }
-
-                       add_wait_queue (&channel->wait, &wait);
-
-                       for (;;) {
-                               if (channel->active == 0)
-                                       break;
-
-                               if (channel->filled_frags)
-                                       break;
-                                               
-                               spin_unlock_irqrestore (&chip->lock, flags);
-
-                               set_current_state (TASK_INTERRUPTIBLE);
-                               schedule();
-
-                               spin_lock_irqsave (&chip->lock, flags);
-                       }
-
-                       set_current_state (TASK_RUNNING);
-                       remove_wait_queue (&channel->wait, &wait);
-               }
-
-               if (i > channel->frag_sz)
-                       sz = channel->frag_sz;
-               else
-                       sz = i;
-
-               spin_unlock_irqrestore (&chip->lock, flags);
-
-               if (copy_to_user (buffer, (void *)channel->buf+channel->swptr, sz)) {
-                       DPRINTK ("%s: copy_to_user failed\n", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               spin_lock_irqsave (&chip->lock, flags);
-
-               /* Advance software pointer */
-               buffer += sz;
-               if (channel->filled_frags > 0)
-                       channel->filled_frags--;
-               channel->swptr += channel->frag_sz;
-               channel->swptr %= channel->buf_sz;
-               i -= sz;
-       }
-
-       spin_unlock_irqrestore (&chip->lock, flags);
-
-       return bytes - i;
-}
-
-
-static struct file_operations forte_dsp_fops = {
-       .owner                  = THIS_MODULE,
-       .llseek                 = &no_llseek,
-       .read                   = &forte_dsp_read,
-       .write                  = &forte_dsp_write,
-       .poll                   = &forte_dsp_poll,
-       .ioctl                  = &forte_dsp_ioctl,
-       .open                   = &forte_dsp_open,
-       .release                = &forte_dsp_release,
-       .mmap                   = &forte_dsp_mmap,
-};
-
-
-/* Common ------------------------------------------------------------------ */
-
-
-/**
- * forte_interrupt:
- */
-
-static irqreturn_t
-forte_interrupt (int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct forte_chip *chip = dev_id;
-       struct forte_channel *channel = NULL;
-       u16 status, count; 
-
-       status = inw (chip->iobase + FORTE_IRQ_STATUS);
-
-       /* If this is not for us, get outta here ASAP */
-       if ((status & (FORTE_IRQ_PLAYBACK | FORTE_IRQ_CAPTURE)) == 0)
-               return IRQ_NONE;
-       
-       if (status & FORTE_IRQ_PLAYBACK) {
-               channel = &chip->play;
-
-               spin_lock (&chip->lock);
-
-               if (channel->frag_sz == 0)
-                       goto pack;
-
-               /* Declare a fragment done */
-               if (channel->filled_frags > 0)
-                       channel->filled_frags--;
-               channel->bytes += channel->frag_sz;
-               channel->nr_irqs++;
-               
-               /* Flip-flop between buffer I and II */
-               channel->next_buf ^= 1;
-
-               /* Advance hardware pointer by fragment size and wrap around */
-               channel->hwptr += channel->frag_sz;
-               channel->hwptr %= channel->buf_sz;
-
-               /* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-                     channel->next_buf == 0 ?
-                     channel->iobase + FORTE_PLY_BUF1 :
-                     channel->iobase + FORTE_PLY_BUF2);
-
-               /* If the currently playing fragment is last, schedule pause */
-               if (channel->filled_frags == 1) 
-                       forte_channel_pause (channel);
-
-       pack:
-               /* Acknowledge interrupt */
-                outw (FORTE_IRQ_PLAYBACK, chip->iobase + FORTE_IRQ_STATUS);
-
-               if (waitqueue_active (&channel->wait)) 
-                       wake_up_all (&channel->wait);
-
-               spin_unlock (&chip->lock);
-       }
-
-       if (status & FORTE_IRQ_CAPTURE) {
-               channel = &chip->rec;
-               spin_lock (&chip->lock);
-
-               /* One fragment filled */
-               channel->filled_frags++;
-
-               /* Get # of completed bytes */
-               count = inw (channel->iobase + FORTE_PLY_COUNT) + 1;
-
-               if (count == 0) {
-                       DPRINTK ("%s: last, filled_frags = %d\n", __FUNCTION__,
-                                channel->filled_frags);
-                       channel->filled_frags = 0;
-                       goto rack;
-               }
-
-               /* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-                     channel->next_buf == 0 ?
-                     channel->iobase + FORTE_PLY_BUF1 :
-                     channel->iobase + FORTE_PLY_BUF2);
-
-               /* Flip-flop between buffer I and II */
-               channel->next_buf ^= 1;
-
-               /* Advance hardware pointer by fragment size and wrap around */
-               channel->hwptr += channel->frag_sz;
-               channel->hwptr %= channel->buf_sz;
-
-               /* Out of buffers */
-               if (channel->filled_frags == channel->frag_num - 1)
-                       forte_channel_stop (channel);
-       rack:
-               /* Acknowledge interrupt */
-                outw (FORTE_IRQ_CAPTURE, chip->iobase + FORTE_IRQ_STATUS);
-
-               spin_unlock (&chip->lock);
-
-               if (waitqueue_active (&channel->wait))
-                       wake_up_all (&channel->wait);           
-       }
-
-       return IRQ_HANDLED;
-}
-
-
-/**
- * forte_proc_read:
- */
-
-static int
-forte_proc_read (char *page, char **start, off_t off, int count, 
-                int *eof, void *data)
-{
-       int i = 0, p_rate, p_chan, r_rate;
-       unsigned short p_reg, r_reg;
-
-       i += sprintf (page, "ForteMedia FM801 OSS Lite driver\n%s\n \n", 
-                     DRIVER_VERSION);
-
-       if (!forte->iobase)
-               return i;
-
-       p_rate = p_chan = -1;
-       p_reg  = inw (forte->iobase + FORTE_PLY_CTRL);
-       p_rate = (p_reg >> 8) & 15;
-       p_chan = (p_reg >> 12) & 3;
-
-       if (p_rate >= 0 || p_rate <= 10)
-               p_rate = rates[p_rate];
-
-       if (p_chan >= 0 || p_chan <= 2)
-               p_chan = channels[p_chan];
-
-       r_rate = -1;
-       r_reg  = inw (forte->iobase + FORTE_CAP_CTRL);
-       r_rate = (r_reg >> 8) & 15;
-
-       if (r_rate >= 0 || r_rate <= 10)
-               r_rate = rates[r_rate]; 
-
-       i += sprintf (page + i,
-                     "             Playback  Capture\n"
-                     "FIFO empty : %-3s       %-3s\n"
-                     "Buf1 Last  : %-3s       %-3s\n"
-                     "Buf2 Last  : %-3s       %-3s\n"
-                     "Started    : %-3s       %-3s\n"
-                     "Paused     : %-3s       %-3s\n"
-                     "Immed Stop : %-3s       %-3s\n"
-                     "Rate       : %-5d     %-5d\n"
-                     "Channels   : %-5d     -\n"
-                     "16-bit     : %-3s       %-3s\n"
-                     "Stereo     : %-3s       %-3s\n"
-                     " \n"
-                     "Buffer Sz  : %-6d    %-6d\n"
-                     "Frag Sz    : %-6d    %-6d\n"
-                     "Frag Num   : %-6d    %-6d\n"
-                     "Frag msecs : %-6d    %-6d\n"
-                     "Used Frags : %-6d    %-6d\n"
-                     "Mapped     : %-3s       %-3s\n",
-                     p_reg & 1<<0  ? "yes" : "no",
-                     r_reg & 1<<0  ? "yes" : "no",
-                     p_reg & 1<<1  ? "yes" : "no",
-                     r_reg & 1<<1  ? "yes" : "no",
-                     p_reg & 1<<2  ? "yes" : "no",
-                     r_reg & 1<<2  ? "yes" : "no",
-                     p_reg & 1<<5  ? "yes" : "no",
-                     r_reg & 1<<5  ? "yes" : "no",
-                     p_reg & 1<<6  ? "yes" : "no",
-                     r_reg & 1<<6  ? "yes" : "no",
-                     p_reg & 1<<7  ? "yes" : "no",
-                     r_reg & 1<<7  ? "yes" : "no",
-                     p_rate, r_rate,
-                     p_chan,
-                     p_reg & 1<<14 ? "yes" : "no",
-                     r_reg & 1<<14 ? "yes" : "no",
-                     p_reg & 1<<15 ? "yes" : "no",
-                     r_reg & 1<<15 ? "yes" : "no",
-                     forte->play.buf_sz,       forte->rec.buf_sz,
-                     forte->play.frag_sz,      forte->rec.frag_sz,
-                     forte->play.frag_num,     forte->rec.frag_num,
-                     forte->play.frag_msecs,   forte->rec.frag_msecs,
-                     forte->play.filled_frags, forte->rec.filled_frags,
-                     forte->play.mapped ? "yes" : "no",
-                     forte->rec.mapped ? "yes" : "no"
-               );
-
-       return i;
-}
-
-
-/**
- * forte_proc_init:
- *
- * Creates driver info entries in /proc
- */
-
-static int __init 
-forte_proc_init (void)
-{
-       if (!proc_mkdir ("driver/forte", NULL))
-               return -EIO;
-
-       if (!create_proc_read_entry ("driver/forte/chip", 0, NULL, forte_proc_read, forte)) {
-               remove_proc_entry ("driver/forte", NULL);
-               return -EIO;
-       }
-
-       if (!create_proc_read_entry("driver/forte/ac97", 0, NULL, ac97_read_proc, forte->ac97)) {
-               remove_proc_entry ("driver/forte/chip", NULL);
-               remove_proc_entry ("driver/forte", NULL);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-
-/**
- * forte_proc_remove:
- *
- * Removes driver info entries in /proc
- */
-
-static void
-forte_proc_remove (void)
-{
-       remove_proc_entry ("driver/forte/ac97", NULL);
-       remove_proc_entry ("driver/forte/chip", NULL);
-       remove_proc_entry ("driver/forte", NULL);       
-}
-
-
-/**
- * forte_chip_init:
- * @chip:      Chip instance to initialize
- *
- * Description:
- *             Resets chip, configures codec and registers the driver with
- *             the sound subsystem.
- *
- *             Press and hold Start for 8 secs, then switch on Run
- *             and hold for 4 seconds.  Let go of Start.  Numbers
- *             assume a properly oiled TWG.
- */
-
-static int __devinit
-forte_chip_init (struct forte_chip *chip)
-{
-       u8 revision;
-       u16 cmdw;
-       struct ac97_codec *codec;
-
-       pci_read_config_byte (chip->pci_dev, PCI_REVISION_ID, &revision);
-
-       if (revision >= 0xB1) {
-               chip->multichannel = 1;
-               printk (KERN_INFO PFX "Multi-channel device detected.\n");
-       }
-
-       /* Reset chip */
-       outw (FORTE_CC_CODEC_RESET | FORTE_CC_AC97_RESET, 
-             chip->iobase + FORTE_CODEC_CTRL);
-       udelay(100);
-       outw (0, chip->iobase + FORTE_CODEC_CTRL);
-
-       /* Request read from AC97 */
-       outw (FORTE_AC97_READ | (0 << FORTE_AC97_ADDR_SHIFT), 
-             chip->iobase + FORTE_AC97_CMD);
-       mdelay(750);
-
-       if ((inw (chip->iobase + FORTE_AC97_CMD) & (3<<8)) != (1<<8)) {
-               printk (KERN_INFO PFX "AC97 codec not responding");
-               return -EIO;
-       }
-
-       /* Init volume */
-       outw (0x0808, chip->iobase + FORTE_PCM_VOL);
-       outw (0x9f1f, chip->iobase + FORTE_FM_VOL);
-       outw (0x8808, chip->iobase + FORTE_I2S_VOL);
-
-       /* I2S control - I2S mode */
-       outw (0x0003, chip->iobase + FORTE_I2S_MODE);
-
-       /* Interrupt setup - unmask PLAYBACK & CAPTURE */
-       cmdw = inw (chip->iobase + FORTE_IRQ_MASK);
-       cmdw &= ~0x0003;
-       outw (cmdw, chip->iobase + FORTE_IRQ_MASK);
-
-       /* Interrupt clear */
-       outw (FORTE_IRQ_PLAYBACK|FORTE_IRQ_CAPTURE, 
-             chip->iobase + FORTE_IRQ_STATUS);
-
-       /* Set up the AC97 codec */
-       if ((codec = ac97_alloc_codec()) == NULL)
-               return -ENOMEM;
-       codec->private_data = chip;
-       codec->codec_read = forte_ac97_read;
-       codec->codec_write = forte_ac97_write;
-       codec->id = 0;
-
-       if (ac97_probe_codec (codec) == 0) {
-               printk (KERN_ERR PFX "codec probe failed\n");
-               ac97_release_codec(codec);
-               return -1;
-       }
-
-       /* Register mixer */
-       if ((codec->dev_mixer = 
-            register_sound_mixer (&forte_mixer_fops, -1)) < 0) {
-               printk (KERN_ERR PFX "couldn't register mixer!\n");
-               ac97_release_codec(codec);
-               return -1;
-       }
-
-       chip->ac97 = codec;
-
-       /* Register DSP */
-       if ((chip->dsp = register_sound_dsp (&forte_dsp_fops, -1) ) < 0) {
-               printk (KERN_ERR PFX "couldn't register dsp!\n");
-               return -1;
-       }
-
-       /* Register with /proc */
-       if (forte_proc_init()) {
-               printk (KERN_ERR PFX "couldn't add entries to /proc!\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/**
- * forte_probe:
- * @pci_dev:   PCI struct for probed device
- * @pci_id:    
- *
- * Description:
- *             Allocates chip instance, I/O region, and IRQ
- */
-static int __init 
-forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-       struct forte_chip *chip;
-       int ret = 0;
-
-       /* FIXME: Support more than one chip */
-       if (found++)
-               return -EIO;
-
-       /* Ignition */
-       if (pci_enable_device (pci_dev))
-               return -EIO;
-
-       pci_set_master (pci_dev);
-
-       /* Allocate chip instance and configure */
-       forte = (struct forte_chip *) 
-               kmalloc (sizeof (struct forte_chip), GFP_KERNEL);
-       chip = forte;
-
-       if (chip == NULL) {
-               printk (KERN_WARNING PFX "Out of memory");
-               return -ENOMEM;
-       }
-
-       memset (chip, 0, sizeof (struct forte_chip));
-       chip->pci_dev = pci_dev;
-
-       mutex_init(&chip->open_mutex);
-       spin_lock_init (&chip->lock);
-       spin_lock_init (&chip->ac97_lock);
-
-       if (! request_region (pci_resource_start (pci_dev, 0),
-                             pci_resource_len (pci_dev, 0), DRIVER_NAME)) {
-               printk (KERN_WARNING PFX "Unable to reserve I/O space");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       chip->iobase = pci_resource_start (pci_dev, 0);
-       chip->irq = pci_dev->irq;
-
-       if (request_irq (chip->irq, forte_interrupt, IRQF_SHARED, DRIVER_NAME,
-                        chip)) {
-               printk (KERN_WARNING PFX "Unable to reserve IRQ");
-               ret = -EIO;
-               goto error;
-       }               
-       
-       pci_set_drvdata (pci_dev, chip);
-
-       printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%16llX IRQ %u\n",
-               chip->iobase, (unsigned long long)pci_resource_end (pci_dev, 0),
-               chip->irq);
-
-       /* Power it up */
-       if ((ret = forte_chip_init (chip)) == 0)
-               return 0;
-
- error:
-       if (chip->irq)
-               free_irq (chip->irq, chip);
-
-       if (chip->iobase) 
-               release_region (pci_resource_start (pci_dev, 0),
-                               pci_resource_len (pci_dev, 0));
-               
-       kfree (chip);
-
-       return ret;
-}
-
-
-/**
- * forte_remove:
- * @pci_dev:   PCI device to unclaim
- *
- */
-
-static void 
-forte_remove (struct pci_dev *pci_dev)
-{
-       struct forte_chip *chip = pci_get_drvdata (pci_dev);
-
-       if (chip == NULL)
-               return;
-
-       /* Turn volume down to avoid popping */
-       outw (0x1f1f, chip->iobase + FORTE_PCM_VOL);
-       outw (0x1f1f, chip->iobase + FORTE_FM_VOL);
-       outw (0x1f1f, chip->iobase + FORTE_I2S_VOL);
-
-       forte_proc_remove();
-       free_irq (chip->irq, chip);
-       release_region (chip->iobase, pci_resource_len (pci_dev, 0));
-
-       unregister_sound_dsp (chip->dsp);
-       unregister_sound_mixer (chip->ac97->dev_mixer);
-       ac97_release_codec(chip->ac97);
-       kfree (chip);
-
-       printk (KERN_INFO PFX "driver released\n");
-}
-
-
-static struct pci_device_id forte_pci_ids[] = {
-       { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0, }
-};
-
-
-static struct pci_driver forte_pci_driver = {
-       .name                   = DRIVER_NAME,
-       .id_table               = forte_pci_ids,
-       .probe                  = forte_probe,
-       .remove                 = forte_remove,
-
-};
-
-
-/**
- * forte_init_module:
- *
- */
-
-static int __init
-forte_init_module (void)
-{
-       printk (KERN_INFO PFX DRIVER_VERSION "\n");
-
-       return pci_register_driver (&forte_pci_driver);
-}
-
-
-/**
- * forte_cleanup_module:
- *
- */
-
-static void __exit 
-forte_cleanup_module (void)
-{
-       pci_unregister_driver (&forte_pci_driver);
-}
-
-
-module_init(forte_init_module);
-module_exit(forte_cleanup_module);
-
-MODULE_AUTHOR("Martin K. Petersen <mkp@mkp.net>");
-MODULE_DESCRIPTION("ForteMedia FM801 OSS Driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE (pci, forte_pci_ids);
diff --git a/sound/oss/gus.h b/sound/oss/gus.h
deleted file mode 100644 (file)
index 3d5271b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include "ad1848.h"
-
-/*     From gus_card.c */
-int gus_set_midi_irq(int num);
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs * dummy);
-
-/*     From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-void gus_wave_init(struct address_info *hw_config);
-void gus_wave_unload (struct address_info *hw_config);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, void __user *arg);
-void gus_timer_command (unsigned int addr, unsigned int val);
-
-/*     From gus_midi.c */
-void gus_midi_init(struct address_info *hw_config);
-void gus_midi_interrupt(int dummy);
-
-/*     From ics2101.c */
-int ics2101_mixer_init(void);
diff --git a/sound/oss/gus_card.c b/sound/oss/gus_card.c
deleted file mode 100644 (file)
index dbb2977..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * sound/gus_card.c
- *
- * Detection routine for the Gravis Ultrasound.
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- *
- * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
- *
- * Status:
- *              Tested... 
- */
-      
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy);
-
-int             gus_base = 0, gus_irq = 0, gus_dma = 0;
-int             gus_no_wave_dma = 0; 
-extern int      gus_wave_volume;
-extern int      gus_pcm_volume;
-extern int      have_gus_max;
-int             gus_pnp_flag = 0;
-#ifdef CONFIG_SOUND_GUS16
-static int      db16;  /* Has a Gus16 AD1848 on it */
-#endif
-
-static void __init attach_gus(struct address_info *hw_config)
-{
-       gus_wave_init(hw_config);
-
-       if (sound_alloc_dma(hw_config->dma, "GUS"))
-               printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
-       if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-               if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
-                       printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
-       gus_midi_init(hw_config);
-       if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
-               printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
-
-       return;
-}
-
-static int __init probe_gus(struct address_info *hw_config)
-{
-       int             irq;
-       int             io_addr;
-
-       if (hw_config->card_subtype == 1)
-               gus_pnp_flag = 1;
-
-       irq = hw_config->irq;
-
-       if (hw_config->card_subtype == 0)       /* GUS/MAX/ACE */
-               if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
-                   irq != 11 && irq != 12 && irq != 15)
-                 {
-                         printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
-                         return 0;
-                 }
-       if (gus_wave_detect(hw_config->io_base))
-               return 1;
-
-#ifndef EXCLUDE_GUS_IODETECT
-
-       /*
-        * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
-        */
-
-       for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) {
-               if (io_addr == hw_config->io_base)      /* Already tested */
-                       continue;
-               if (gus_wave_detect(io_addr)) {
-                       hw_config->io_base = io_addr;
-                       return 1;
-               }
-       }
-#endif
-
-       printk("NO GUS card found !\n");
-       return 0;
-}
-
-static void __exit unload_gus(struct address_info *hw_config)
-{
-       DDB(printk("unload_gus(%x)\n", hw_config->io_base));
-
-       gus_wave_unload(hw_config);
-
-       release_region(hw_config->io_base, 16);
-       release_region(hw_config->io_base + 0x100, 12);         /* 0x10c-> is MAX */
-       free_irq(hw_config->irq, hw_config);
-
-       sound_free_dma(hw_config->dma);
-
-       if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-               sound_free_dma(hw_config->dma2);
-}
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       unsigned char src;
-       extern int gus_timer_enabled;
-       int handled = 0;
-
-#ifdef CONFIG_SOUND_GUSMAX
-       if (have_gus_max) {
-               struct address_info *hw_config = dev_id;
-               adintr(irq, (void *)hw_config->slots[1], NULL);
-       }
-#endif
-#ifdef CONFIG_SOUND_GUS16
-       if (db16) {
-               struct address_info *hw_config = dev_id;
-               adintr(irq, (void *)hw_config->slots[3], NULL);
-       }
-#endif
-
-       while (1)
-       {
-               if (!(src = inb(u_IrqStatus)))
-                       break;
-               handled = 1;
-               if (src & DMA_TC_IRQ)
-               {
-                       guswave_dma_irq();
-               }
-               if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
-               {
-                       gus_midi_interrupt(0);
-               }
-               if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
-               {
-                       if (gus_timer_enabled)
-                               sound_timer_interrupt();
-                       gus_write8(0x45, 0);    /* Ack IRQ */
-                       gus_timer_command(4, 0x80);             /* Reset IRQ flags */
-               }
-               if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
-                       gus_voice_irq();
-       }
-       return IRQ_RETVAL(handled);
-}
-
-/*
- *     Some extra code for the 16 bit sampling option
- */
-
-#ifdef CONFIG_SOUND_GUS16
-
-static int __init init_gus_db16(struct address_info *hw_config)
-{
-       struct resource *ports;
-
-       ports = request_region(hw_config->io_base, 4, "ad1848");
-       if (!ports)
-               return 0;
-
-       if (!ad1848_detect(ports, NULL, hw_config->osp)) {
-               release_region(hw_config->io_base, 4);
-               return 0;
-       }
-
-       gus_pcm_volume = 100;
-       gus_wave_volume = 90;
-
-       hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports,
-                                         hw_config->irq,
-                                         hw_config->dma,
-                                         hw_config->dma, 0,
-                                         hw_config->osp,
-                                         THIS_MODULE);
-       return 1;
-}
-
-static void __exit unload_gus_db16(struct address_info *hw_config)
-{
-
-       ad1848_unload(hw_config->io_base,
-                     hw_config->irq,
-                     hw_config->dma,
-                     hw_config->dma, 0);
-       sound_unload_audiodev(hw_config->slots[3]);
-}
-#endif
-
-#ifdef CONFIG_SOUND_GUS16
-static int gus16;
-#endif
-#ifdef CONFIG_SOUND_GUSMAX
-static int no_wave_dma;   /* Set if no dma is to be used for the
-                                   wave table (GF1 chip) */
-#endif
-
-
-/*
- *    Note DMA2 of -1 has the right meaning in the GUS driver as well
- *      as here. 
- */
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1;      /* Set this for modules that need it */
-static int __initdata type = 0;                /* 1 for PnP */
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(type, int, 0);
-#ifdef CONFIG_SOUND_GUSMAX
-module_param(no_wave_dma, int, 0);
-#endif
-#ifdef CONFIG_SOUND_GUS16
-module_param(db16, int, 0);
-module_param(gus16, int, 0);
-#endif
-MODULE_LICENSE("GPL");
-
-static int __init init_gus(void)
-{
-       printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma16;
-       cfg.card_subtype = type;
-#ifdef CONFIG_SOUND_GUSMAX
-       gus_no_wave_dma = no_wave_dma;
-#endif
-
-       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-               printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
-               return -EINVAL;
-       }
-
-#ifdef CONFIG_SOUND_GUS16
-       if (gus16 && init_gus_db16(&cfg))
-               db16 = 1;
-#endif
-       if (!probe_gus(&cfg))
-               return -ENODEV;
-       attach_gus(&cfg);
-
-       return 0;
-}
-
-static void __exit cleanup_gus(void)
-{
-#ifdef CONFIG_SOUND_GUS16
-       if (db16)
-               unload_gus_db16(&cfg);
-#endif
-       unload_gus(&cfg);
-}
-
-module_init(init_gus);
-module_exit(cleanup_gus);
-
-#ifndef MODULE
-static int __init setup_gus(char *str)
-{
-       /* io, irq, dma, dma2 */
-       int ints[5];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma16   = ints[4];
-
-       return 1;
-}
-
-__setup("gus=", setup_gus);
-#endif
diff --git a/sound/oss/gus_hw.h b/sound/oss/gus_hw.h
deleted file mode 100644 (file)
index f97a0b8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * I/O addresses
- */
-
-#define u_Base                 (gus_base + 0x000)
-#define u_Mixer                        u_Base
-#define u_Status               (gus_base + 0x006)
-#define u_TimerControl         (gus_base + 0x008)
-#define u_TimerData            (gus_base + 0x009)
-#define u_IRQDMAControl                (gus_base + 0x00b)
-#define u_MidiControl          (gus_base + 0x100)
-#define        MIDI_RESET              0x03
-#define                MIDI_ENABLE_XMIT        0x20
-#define                MIDI_ENABLE_RCV         0x80
-#define u_MidiStatus           u_MidiControl
-#define                MIDI_RCV_FULL           0x01
-#define        MIDI_XMIT_EMPTY         0x02
-#define        MIDI_FRAME_ERR          0x10
-#define        MIDI_OVERRUN            0x20
-#define        MIDI_IRQ_PEND           0x80
-#define u_MidiData             (gus_base + 0x101)
-#define u_Voice                        (gus_base + 0x102)
-#define u_Command              (gus_base + 0x103)
-#define u_DataLo               (gus_base + 0x104)
-#define u_DataHi               (gus_base + 0x105)
-#define u_MixData               (gus_base + 0x106)   /* Rev. 3.7+ mixing */
-#define u_MixSelect             (gus_base + 0x506)   /* registers.       */
-#define u_IrqStatus            u_Status
-#      define MIDI_TX_IRQ              0x01    /* pending MIDI xmit IRQ */
-#      define MIDI_RX_IRQ              0x02    /* pending MIDI recv IRQ */
-#      define GF1_TIMER1_IRQ           0x04    /* general purpose timer */
-#      define GF1_TIMER2_IRQ           0x08    /* general purpose timer */
-#      define WAVETABLE_IRQ            0x20    /* pending wavetable IRQ */
-#      define ENVELOPE_IRQ             0x40    /* pending volume envelope IRQ */
-#      define DMA_TC_IRQ               0x80    /* pending dma tc IRQ */
-
-#define ICS2101                1
-#      define ICS_MIXDEVS      6
-#      define DEV_MIC          0
-#      define DEV_LINE         1
-#      define DEV_CD           2
-#      define DEV_GF1          3
-#      define DEV_UNUSED       4
-#      define DEV_VOL          5
-
-#      define CHN_LEFT         0
-#      define CHN_RIGHT        1
-#define CS4231         2
-#define u_DRAMIO               (gus_base + 0x107)
diff --git a/sound/oss/gus_linearvol.h b/sound/oss/gus_linearvol.h
deleted file mode 100644 (file)
index 7ad0c30..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-static unsigned short gus_linearvol[128] = {
- 0x0000, 0x08ff, 0x09ff, 0x0a80, 0x0aff, 0x0b40, 0x0b80, 0x0bc0,
- 0x0bff, 0x0c20, 0x0c40, 0x0c60, 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0,
- 0x0cff, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70,
- 0x0d80, 0x0d90, 0x0da0, 0x0db0, 0x0dc0, 0x0dd0, 0x0de0, 0x0df0,
- 0x0dff, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38,
- 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78,
- 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8,
- 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8,
- 0x0eff, 0x0f04, 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c,
- 0x0f20, 0x0f24, 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3c,
- 0x0f40, 0x0f44, 0x0f48, 0x0f4c, 0x0f50, 0x0f54, 0x0f58, 0x0f5c,
- 0x0f60, 0x0f64, 0x0f68, 0x0f6c, 0x0f70, 0x0f74, 0x0f78, 0x0f7c,
- 0x0f80, 0x0f84, 0x0f88, 0x0f8c, 0x0f90, 0x0f94, 0x0f98, 0x0f9c,
- 0x0fa0, 0x0fa4, 0x0fa8, 0x0fac, 0x0fb0, 0x0fb4, 0x0fb8, 0x0fbc,
- 0x0fc0, 0x0fc4, 0x0fc8, 0x0fcc, 0x0fd0, 0x0fd4, 0x0fd8, 0x0fdc,
- 0x0fe0, 0x0fe4, 0x0fe8, 0x0fec, 0x0ff0, 0x0ff4, 0x0ff8, 0x0ffc
-};
diff --git a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c
deleted file mode 100644 (file)
index b48f57c..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * sound/gus2_midi.c
- *
- * The low level driver for the GUS Midi Interface.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added __init to gus_midi_init()
- */
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-static int      midi_busy, input_opened;
-static int      my_dev;
-static int      output_used;
-static volatile unsigned char gus_midi_control;
-static void     (*midi_input_intr) (int dev, unsigned char data);
-
-static unsigned char tmp_queue[256];
-extern int      gus_pnp_flag;
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-extern int      gus_base, gus_irq, gus_dma;
-extern int     *gus_osp;
-extern spinlock_t gus_lock;
-
-static int GUS_MIDI_STATUS(void)
-{
-       return inb(u_MidiStatus);
-}
-
-static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
-{
-       if (midi_busy)
-       {
-/*             printk("GUS: Midi busy\n");*/
-               return -EBUSY;
-       }
-       outb((MIDI_RESET), u_MidiControl);
-       gus_delay();
-
-       gus_midi_control = 0;
-       input_opened = 0;
-
-       if (mode == OPEN_READ || mode == OPEN_READWRITE)
-               if (!gus_pnp_flag)
-               {
-                       gus_midi_control |= MIDI_ENABLE_RCV;
-                       input_opened = 1;
-               }
-       outb((gus_midi_control), u_MidiControl);        /* Enable */
-
-       midi_busy = 1;
-       qlen = qhead = qtail = output_used = 0;
-       midi_input_intr = input;
-
-       return 0;
-}
-
-static int dump_to_midi(unsigned char midi_byte)
-{
-       unsigned long   flags;
-       int             ok = 0;
-
-       output_used = 1;
-
-       spin_lock_irqsave(&gus_lock, flags);
-
-       if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
-       {
-               ok = 1;
-               outb((midi_byte), u_MidiData);
-       }
-       else
-       {
-               /*
-                * Enable Midi xmit interrupts (again)
-                */
-               gus_midi_control |= MIDI_ENABLE_XMIT;
-               outb((gus_midi_control), u_MidiControl);
-       }
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return ok;
-}
-
-static void gus_midi_close(int dev)
-{
-       /*
-        * Reset FIFO pointers, disable intrs
-        */
-
-       outb((MIDI_RESET), u_MidiControl);
-       midi_busy = 0;
-}
-
-static int gus_midi_out(int dev, unsigned char midi_byte)
-{
-       unsigned long   flags;
-
-       /*
-        * Drain the local queue first
-        */
-       spin_lock_irqsave(&gus_lock, flags);
-
-       while (qlen && dump_to_midi(tmp_queue[qhead]))
-       {
-               qlen--;
-               qhead++;
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       /*
-        *      Output the byte if the local queue is empty.
-        */
-
-       if (!qlen)
-               if (dump_to_midi(midi_byte))
-                       return 1;       /*
-                                        * OK
-                                        */
-
-       /*
-        *      Put to the local queue
-        */
-
-       if (qlen >= 256)
-               return 0;       /*
-                                * Local queue full
-                                */
-       spin_lock_irqsave(&gus_lock, flags);
-
-       tmp_queue[qtail] = midi_byte;
-       qlen++;
-       qtail++;
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return 1;
-}
-
-static int gus_midi_start_read(int dev)
-{
-       return 0;
-}
-
-static int gus_midi_end_read(int dev)
-{
-       return 0;
-}
-
-static void gus_midi_kick(int dev)
-{
-}
-
-static int gus_midi_buffer_status(int dev)
-{
-       unsigned long   flags;
-
-       if (!output_used)
-               return 0;
-
-       spin_lock_irqsave(&gus_lock, flags);
-
-       if (qlen && dump_to_midi(tmp_queue[qhead]))
-       {
-               qlen--;
-               qhead++;
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
-}
-
-#define MIDI_SYNTH_NAME        "Gravis Ultrasound Midi"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct midi_operations gus_midi_operations =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
-       .converter      = &std_midi_synth,
-       .in_info        = {0},
-       .open           = gus_midi_open,
-       .close          = gus_midi_close,
-       .outputc        = gus_midi_out,
-       .start_read     = gus_midi_start_read,
-       .end_read       = gus_midi_end_read,
-       .kick           = gus_midi_kick,
-       .buffer_status  = gus_midi_buffer_status,
-};
-
-void __init gus_midi_init(struct address_info *hw_config)
-{
-       int dev = sound_alloc_mididev();
-
-       if (dev == -1)
-       {
-               printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
-               return;
-       }
-       outb((MIDI_RESET), u_MidiControl);
-
-       std_midi_synth.midi_dev = my_dev = dev;
-       hw_config->slots[2] = dev;
-       midi_devs[dev] = &gus_midi_operations;
-       sequencer_init();
-       return;
-}
-
-void gus_midi_interrupt(int dummy)
-{
-       volatile unsigned char stat, data;
-       int timeout = 10;
-
-       spin_lock(&gus_lock);
-
-       while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
-       {
-               if (stat & MIDI_RCV_FULL)
-               {
-                       data = inb(u_MidiData);
-                       if (input_opened)
-                               midi_input_intr(my_dev, data);
-               }
-               if (stat & MIDI_XMIT_EMPTY)
-               {
-                       while (qlen && dump_to_midi(tmp_queue[qhead]))
-                       {
-                               qlen--;
-                               qhead++;
-                       }
-                       if (!qlen)
-                       {
-                             /*
-                              * Disable Midi output interrupts, since no data in the buffer
-                              */
-                             gus_midi_control &= ~MIDI_ENABLE_XMIT;
-                             outb((gus_midi_control), u_MidiControl);
-                             outb((gus_midi_control), u_MidiControl);
-                       }
-               }
-       }
-       spin_unlock(&gus_lock);
-}
diff --git a/sound/oss/gus_vol.c b/sound/oss/gus_vol.c
deleted file mode 100644 (file)
index 6ae6924..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-
-/*
- * gus_vol.c - Compute volume for GUS.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_linearvol.h"
-
-#define GUS_VOLUME     gus_wave_volume
-
-
-extern int      gus_wave_volume;
-
-/*
- * Calculate gus volume from note velocity, main volume, expression, and
- * intrinsic patch volume given in patch library.  Expression is multiplied
- * in, so it emphasizes differences in note velocity, while main volume is
- * added in -- I don't know whether this is right, but it seems reasonable to
- * me.  (In the previous stage, main volume controller messages were changed
- * to expression controller messages, if they were found to be used for
- * dynamic volume adjustments, so here, main volume can be assumed to be
- * constant throughout a song.)
- *
- * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
- * we can give a big boost to very weak voices like nylon guitar and the
- * basses.  The normal value is 64.  Strings are assigned lower values.
- */
-
-unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
-{
-       int i, m, n, x;
-
-
-       /*
-        * A voice volume of 64 is considered neutral, so adjust the main volume if
-        * something other than this neutral value was assigned in the patch
-        * library.
-        */
-       x = 256 + 6 * (voicev - 64);
-
-       /*
-        * Boost expression by voice volume above neutral.
-        */
-        
-       if (voicev > 65)
-               xpn += voicev - 64;
-       xpn += (voicev - 64) / 2;
-
-       /*
-        * Combine multiplicative and level components.
-        */
-       x = vel * xpn * 6 + (voicev / 4) * x;
-
-#ifdef GUS_VOLUME
-       /*
-        * Further adjustment by installation-specific master volume control
-        * (default 60).
-        */
-       x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-       /*
-        * Experimental support for the channel main volume
-        */
-
-       mainv = (mainv / 2) + 64;       /* Scale to 64 to 127 */
-       x = (x * mainv * mainv) / 16384;
-#endif
-
-       if (x < 2)
-               return (0);
-       else if (x >= 65535)
-               return ((15 << 8) | 255);
-
-       /*
-        * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
-        * mantissa m.
-        */
-        
-       n = x;
-       i = 7;
-       if (n < 128)
-       {
-                 while (i > 0 && n < (1 << i))
-                         i--;
-       }
-       else
-       {
-               while (n > 255)
-               {
-                         n >>= 1;
-                         i++;
-               }
-       }
-       /*
-        * Mantissa is part of linear volume not expressed in exponent.  (This is
-        * not quite like real logs -- I wonder if it's right.)
-        */
-       m = x - (1 << i);
-
-       /*
-        * Adjust mantissa to 8 bits.
-        */
-       if (m > 0)
-       {
-               if (i > 8)
-                       m >>= i - 8;
-               else if (i < 8)
-                       m <<= 8 - i;
-       }
-       return ((i << 8) + m);
-}
-
-/*
- * Volume-values are interpreted as linear values. Volume is based on the
- * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
- * and the volume set by the mixer-device (default 60%).
- */
-
-unsigned short gus_linear_vol(int vol, int mainvol)
-{
-       int mixer_mainvol;
-
-       if (vol <= 0)
-               vol = 0;
-       else if (vol >= 127)
-               vol = 127;
-
-#ifdef GUS_VOLUME
-       mixer_mainvol = GUS_VOLUME;
-#else
-       mixer_mainvol = 100;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-       if (mainvol <= 0)
-               mainvol = 0;
-       else if (mainvol >= 127)
-               mainvol = 127;
-#else
-       mainvol = 127;
-#endif
-       return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
-}
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
deleted file mode 100644 (file)
index 942d518..0000000
+++ /dev/null
@@ -1,3464 +0,0 @@
-/*
- * sound/gus_wave.c
- *
- * Driver for the Gravis UltraSound wave table synth.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer    : ioctl code reworked (vmalloc/vfree removed)
- * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Bartlomiej Zolnierkiewicz : added some __init/__exit
- */
-#include <linux/init.h> 
-#include <linux/config.h>
-#include <linux/spinlock.h>
-
-#define GUSPNP_AUTODETECT
-
-#include "sound_config.h"
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
-
-#define MAX_SAMPLE     150
-#define MAX_PATCH      256
-
-#define NOT_SAMPLE     0xffff
-
-struct voice_info
-{
-       unsigned long   orig_freq;
-       unsigned long   current_freq;
-       unsigned long   mode;
-       int             fixed_pitch;
-       int             bender;
-       int             bender_range;
-       int             panning;
-       int             midi_volume;
-       unsigned int    initial_volume;
-       unsigned int    current_volume;
-       int             loop_irq_mode, loop_irq_parm;
-#define LMODE_FINISH           1
-#define LMODE_PCM              2
-#define LMODE_PCM_STOP         3
-       int             volume_irq_mode, volume_irq_parm;
-#define VMODE_HALT             1
-#define VMODE_ENVELOPE         2
-#define VMODE_START_NOTE       3
-
-       int             env_phase;
-       unsigned char   env_rate[6];
-       unsigned char   env_offset[6];
-
-       /*
-        * Volume computation parameters for gus_adagio_vol()
-        */
-       int             main_vol, expression_vol, patch_vol;
-
-       /* Variables for "Ultraclick" removal */
-       int             dev_pending, note_pending, volume_pending,
-                       sample_pending;
-       char            kill_pending;
-       long            offset_pending;
-
-};
-
-static struct voice_alloc_info *voice_alloc;
-static struct address_info *gus_hw_config;
-extern int      gus_base;
-extern int      gus_irq, gus_dma;
-extern int      gus_pnp_flag;
-extern int      gus_no_wave_dma;
-static int      gus_dma2 = -1;
-static int      dual_dma_mode;
-static long     gus_mem_size;
-static long     free_mem_ptr;
-static int      gus_busy;
-static int      gus_no_dma;
-static int      nr_voices;
-static int      gus_devnum;
-static int      volume_base, volume_scale, volume_method;
-static int      gus_recmask = SOUND_MASK_MIC;
-static int      recording_active;
-static int      only_read_access;
-static int      only_8_bits;
-
-static int      iw_mode = 0;
-int             gus_wave_volume = 60;
-int             gus_pcm_volume = 80;
-int             have_gus_max = 0;
-static int      gus_line_vol = 100, gus_mic_vol;
-static unsigned char mix_image = 0x00;
-
-int             gus_timer_enabled = 0;
-
-/*
- * Current version of this driver doesn't allow synth and PCM functions
- * at the same time. The active_device specifies the active driver
- */
-
-static int      active_device;
-
-#define GUS_DEV_WAVE           1       /* Wave table synth */
-#define GUS_DEV_PCM_DONE       2       /* PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE   3       /* PCM device, transfer done ch. 1/2 */
-
-static int      gus_audio_speed;
-static int      gus_audio_channels;
-static int      gus_audio_bits;
-static int      gus_audio_bsize;
-static char     bounce_buf[8 * 1024];  /* Must match value set to max_fragment */
-
-static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper);
-
-/*
- * Variables and buffers for PCM output
- */
-
-#define MAX_PCM_BUFFERS                (128*MAX_REALTIME_FACTOR)       /* Don't change */
-
-static int      pcm_bsize, pcm_nblk, pcm_banksize;
-static int      pcm_datasize[MAX_PCM_BUFFERS];
-static volatile int pcm_head, pcm_tail, pcm_qlen;
-static volatile int pcm_active;
-static volatile int dma_active;
-static int      pcm_opened;
-static int      pcm_current_dev;
-static int      pcm_current_block;
-static unsigned long pcm_current_buf;
-static int      pcm_current_count;
-static int      pcm_current_intrflag;
-DEFINE_SPINLOCK(gus_lock);
-
-extern int     *gus_osp;
-
-static struct voice_info voices[32];
-
-static int      freq_div_table[] =
-{
-       44100,                  /* 14 */
-       41160,                  /* 15 */
-       38587,                  /* 16 */
-       36317,                  /* 17 */
-       34300,                  /* 18 */
-       32494,                  /* 19 */
-       30870,                  /* 20 */
-       29400,                  /* 21 */
-       28063,                  /* 22 */
-       26843,                  /* 23 */
-       25725,                  /* 24 */
-       24696,                  /* 25 */
-       23746,                  /* 26 */
-       22866,                  /* 27 */
-       22050,                  /* 28 */
-       21289,                  /* 29 */
-       20580,                  /* 30 */
-       19916,                  /* 31 */
-       19293                   /* 32 */
-};
-
-static struct patch_info *samples;
-static long     sample_ptrs[MAX_SAMPLE + 1];
-static int      sample_map[32];
-static int      free_sample;
-static int      mixer_type;
-
-
-static int      patch_table[MAX_PATCH];
-static int      patch_map[32];
-
-static struct synth_info gus_info = {
-       "Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 
-       0, 16, 0, MAX_PATCH
-};
-
-static void     gus_poke(long addr, unsigned char data);
-static void     compute_and_set_volume(int voice, int volume, int ramp_time);
-extern unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol(int vol, int mainvol);
-static void     compute_volume(int voice, int volume);
-static void     do_volume_irq(int voice);
-static void     set_input_volumes(void);
-static void     gus_tmr_install(int io_base);
-
-#define        INSTANT_RAMP            -1      /* Instant change. No ramping */
-#define FAST_RAMP              0       /* Fastest possible ramp */
-
-static void reset_sample_memory(void)
-{
-       int i;
-
-       for (i = 0; i <= MAX_SAMPLE; i++)
-               sample_ptrs[i] = -1;
-       for (i = 0; i < 32; i++)
-               sample_map[i] = -1;
-       for (i = 0; i < 32; i++)
-               patch_map[i] = -1;
-
-       gus_poke(0, 0);         /* Put a silent sample to the beginning */
-       gus_poke(1, 0);
-       free_mem_ptr = 2;
-
-       free_sample = 0;
-
-       for (i = 0; i < MAX_PATCH; i++)
-               patch_table[i] = NOT_SAMPLE;
-}
-
-void gus_delay(void)
-{
-       int i;
-
-       for (i = 0; i < 7; i++)
-               inb(u_DRAMIO);
-}
-
-static void gus_poke(long addr, unsigned char data)
-{                              /* Writes a byte to the DRAM */
-       outb((0x43), u_Command);
-       outb((addr & 0xff), u_DataLo);
-       outb(((addr >> 8) & 0xff), u_DataHi);
-
-       outb((0x44), u_Command);
-       outb(((addr >> 16) & 0xff), u_DataHi);
-       outb((data), u_DRAMIO);
-}
-
-static unsigned char gus_peek(long addr)
-{                              /* Reads a byte from the DRAM */
-       unsigned char   tmp;
-
-       outb((0x43), u_Command);
-       outb((addr & 0xff), u_DataLo);
-       outb(((addr >> 8) & 0xff), u_DataHi);
-
-       outb((0x44), u_Command);
-       outb(((addr >> 16) & 0xff), u_DataHi);
-       tmp = inb(u_DRAMIO);
-
-       return tmp;
-}
-
-void gus_write8(int reg, unsigned int data)
-{                              /* Writes to an indirect register (8 bit) */
-       outb((reg), u_Command);
-       outb(((unsigned char) (data & 0xff)), u_DataHi);
-}
-
-static unsigned char gus_read8(int reg)
-{                              
-       /* Reads from an indirect register (8 bit). Offset 0x80. */
-       unsigned char   val;
-
-       outb((reg | 0x80), u_Command);
-       val = inb(u_DataHi);
-
-       return val;
-}
-
-static unsigned char gus_look8(int reg)
-{
-       /* Reads from an indirect register (8 bit). No additional offset. */
-       unsigned char   val;
-
-       outb((reg), u_Command);
-       val = inb(u_DataHi);
-
-       return val;
-}
-
-static void gus_write16(int reg, unsigned int data)
-{
-       /* Writes to an indirect register (16 bit) */
-       outb((reg), u_Command);
-
-       outb(((unsigned char) (data & 0xff)), u_DataLo);
-       outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi);
-}
-
-static unsigned short gus_read16(int reg)
-{
-       /* Reads from an indirect register (16 bit). Offset 0x80. */
-       unsigned char   hi, lo;
-
-       outb((reg | 0x80), u_Command);
-
-       lo = inb(u_DataLo);
-       hi = inb(u_DataHi);
-
-       return ((hi << 8) & 0xff00) | lo;
-}
-
-static unsigned short gus_look16(int reg)
-{              
-       /* Reads from an indirect register (16 bit). No additional offset. */
-       unsigned char   hi, lo;
-
-       outb((reg), u_Command);
-
-       lo = inb(u_DataLo);
-       hi = inb(u_DataHi);
-
-       return ((hi << 8) & 0xff00) | lo;
-}
-
-static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{
-       /* Writes an 24 bit memory address */
-       unsigned long   hold_address;
-
-       if (is16bit)
-       {
-               if (iw_mode)
-               {
-                       /* Interwave spesific address translations */
-                       address >>= 1;
-               }
-               else
-               {
-                       /*
-                        * Special processing required for 16 bit patches
-                        */
-
-                       hold_address = address;
-                       address = address >> 1;
-                       address &= 0x0001ffffL;
-                       address |= (hold_address & 0x000c0000L);
-               }
-       }
-       gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-       gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-                   + (frac << 5));
-       /* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */
-       gus_delay();
-       gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-       gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-                   + (frac << 5));
-}
-
-static void gus_select_voice(int voice)
-{
-       if (voice < 0 || voice > 31)
-               return;
-       outb((voice), u_Voice);
-}
-
-static void gus_select_max_voices(int nvoices)
-{
-       if (iw_mode)
-               nvoices = 32;
-       if (nvoices < 14)
-               nvoices = 14;
-       if (nvoices > 32)
-               nvoices = 32;
-
-       voice_alloc->max_voice = nr_voices = nvoices;
-       gus_write8(0x0e, (nvoices - 1) | 0xc0);
-}
-
-static void gus_voice_on(unsigned int mode)
-{
-       gus_write8(0x00, (unsigned char) (mode & 0xfc));
-       gus_delay();
-       gus_write8(0x00, (unsigned char) (mode & 0xfc));
-}
-
-static void gus_voice_off(void)
-{
-       gus_write8(0x00, gus_read8(0x00) | 0x03);
-}
-
-static void gus_voice_mode(unsigned int m)
-{
-       unsigned char   mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x00, (gus_read8(0x00) & 0x03) |
-                  (mode & 0xfc));      /* Don't touch last two bits */
-       gus_delay();
-       gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_voice_freq(unsigned long freq)
-{
-       unsigned long   divisor = freq_div_table[nr_voices - 14];
-       unsigned short  fc;
-
-       /* Interwave plays at 44100 Hz with any number of voices */
-       if (iw_mode)
-               fc = (unsigned short) (((freq << 9) + (44100 >> 1)) / 44100);
-       else
-               fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
-       fc = fc << 1;
-
-       gus_write16(0x01, fc);
-}
-
-static void gus_voice_volume(unsigned int vol)
-{
-       gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
-       gus_write16(0x09, (unsigned short) (vol << 4));
-}
-
-static void gus_voice_balance(unsigned int balance)
-{
-       gus_write8(0x0c, (unsigned char) (balance & 0xff));
-}
-
-static void gus_ramp_range(unsigned int low, unsigned int high)
-{
-       gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
-       gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
-}
-
-static void gus_ramp_rate(unsigned int scale, unsigned int rate)
-{
-       gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
-}
-
-static void gus_rampon(unsigned int m)
-{
-       unsigned char   mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x0d, mode & 0xfc);
-       gus_delay();
-       gus_write8(0x0d, mode & 0xfc);
-}
-
-static void gus_ramp_mode(unsigned int m)
-{
-       unsigned char mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
-                  (mode & 0xfc));      /* Leave the last 2 bits alone */
-       gus_delay();
-       gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_rampoff(void)
-{
-       gus_write8(0x0d, 0x03);
-}
-
-static void gus_set_voice_pos(int voice, long position)
-{
-       int sample_no;
-
-       if ((sample_no = sample_map[voice]) != -1) {
-               if (position < samples[sample_no].len) {
-                       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-                               voices[voice].offset_pending = position;
-                       else
-                               gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0,
-                                samples[sample_no].mode & WAVE_16_BITS);
-               }
-       }
-}
-
-static void gus_voice_init(int voice)
-{
-       unsigned long   flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_volume(0);
-       gus_voice_off();
-       gus_write_addr(0x0a, 0, 0, 0);  /* Set current position to 0 */
-       gus_write8(0x00, 0x03); /* Voice off */
-       gus_write8(0x0d, 0x03); /* Ramping off */
-       voice_alloc->map[voice] = 0;
-       voice_alloc->alloc_times[voice] = 0;
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-}
-
-static void gus_voice_init2(int voice)
-{
-       voices[voice].panning = 0;
-       voices[voice].mode = 0;
-       voices[voice].orig_freq = 20000;
-       voices[voice].current_freq = 20000;
-       voices[voice].bender = 0;
-       voices[voice].bender_range = 200;
-       voices[voice].initial_volume = 0;
-       voices[voice].current_volume = 0;
-       voices[voice].loop_irq_mode = 0;
-       voices[voice].loop_irq_parm = 0;
-       voices[voice].volume_irq_mode = 0;
-       voices[voice].volume_irq_parm = 0;
-       voices[voice].env_phase = 0;
-       voices[voice].main_vol = 127;
-       voices[voice].patch_vol = 127;
-       voices[voice].expression_vol = 127;
-       voices[voice].sample_pending = -1;
-       voices[voice].fixed_pitch = 0;
-}
-
-static void step_envelope(int voice)
-{
-       unsigned        vol, prev_vol, phase;
-       unsigned char   rate;
-       unsigned long flags;
-
-       if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
-       {
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(voice);
-               gus_rampoff();
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-               /*
-                * Sustain phase begins. Continue envelope after receiving note off.
-                */
-       }
-       if (voices[voice].env_phase >= 5)
-       {
-               /* Envelope finished. Shoot the voice down */
-               gus_voice_init(voice);
-               return;
-       }
-       prev_vol = voices[voice].current_volume;
-       phase = ++voices[voice].env_phase;
-       compute_volume(voice, voices[voice].midi_volume);
-       vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
-       rate = voices[voice].env_rate[phase];
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       gus_voice_volume(prev_vol);
-
-
-       gus_write8(0x06, rate); /* Ramping rate */
-
-       voices[voice].volume_irq_mode = VMODE_ENVELOPE;
-
-       if (((vol - prev_vol) / 64) == 0)       /* No significant volume change */
-       {
-               spin_unlock_irqrestore(&gus_lock,flags);
-               step_envelope(voice);           /* Continue the envelope on the next step */
-               return;
-       }
-       if (vol > prev_vol)
-       {
-               if (vol >= (4096 - 64))
-                       vol = 4096 - 65;
-               gus_ramp_range(0, vol);
-               gus_rampon(0x20);       /* Increasing volume, with IRQ */
-       }
-       else
-       {
-               if (vol <= 64)
-                       vol = 65;
-               gus_ramp_range(vol, 4030);
-               gus_rampon(0x60);       /* Decreasing volume, with IRQ */
-       }
-       voices[voice].current_volume = vol;
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void init_envelope(int voice)
-{
-       voices[voice].env_phase = -1;
-       voices[voice].current_volume = 64;
-
-       step_envelope(voice);
-}
-
-static void start_release(int voice)
-{
-       if (gus_read8(0x00) & 0x03)
-               return;         /* Voice already stopped */
-
-       voices[voice].env_phase = 2;    /* Will be incremented by step_envelope */
-
-       voices[voice].current_volume = voices[voice].initial_volume =
-                                               gus_read16(0x09) >> 4;  /* Get current volume */
-
-       voices[voice].mode &= ~WAVE_SUSTAIN_ON;
-       gus_rampoff();
-       step_envelope(voice);
-}
-
-static void gus_voice_fade(int voice)
-{
-       int instr_no = sample_map[voice], is16bits;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       if (instr_no < 0 || instr_no > MAX_SAMPLE)
-       {
-               gus_write8(0x00, 0x03); /* Hard stop */
-               voice_alloc->map[voice] = 0;
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0;     /* 8 or 16 bits */
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               start_release(voice);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       /*
-        * Ramp the volume down but not too quickly.
-        */
-       if ((int) (gus_read16(0x09) >> 4) < 100)        /* Get current volume */
-       {
-               gus_voice_off();
-               gus_rampoff();
-               gus_voice_init(voice);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       gus_ramp_range(65, 4030);
-       gus_ramp_rate(2, 4);
-       gus_rampon(0x40 | 0x20);        /* Down, once, with IRQ */
-       voices[voice].volume_irq_mode = VMODE_HALT;
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_reset(void)
-{
-       int i;
-
-       gus_select_max_voices(24);
-       volume_base = 3071;
-       volume_scale = 4;
-       volume_method = VOL_METHOD_ADAGIO;
-
-       for (i = 0; i < 32; i++)
-       {
-               gus_voice_init(i);      /* Turn voice off */
-               gus_voice_init2(i);
-       }
-}
-
-static void gus_initialize(void)
-{
-       unsigned long flags;
-       unsigned char dma_image, irq_image, tmp;
-
-       static unsigned char gus_irq_map[16] =  {
-               0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
-       };
-
-       static unsigned char gus_dma_map[8] = {
-               0, 1, 0, 2, 0, 3, 4, 5
-       };
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_write8(0x4c, 0);    /* Reset GF1 */
-       gus_delay();
-       gus_delay();
-
-       gus_write8(0x4c, 1);    /* Release Reset */
-       gus_delay();
-       gus_delay();
-
-       /*
-        * Clear all interrupts
-        */
-
-       gus_write8(0x41, 0);    /* DMA control */
-       gus_write8(0x45, 0);    /* Timer control */
-       gus_write8(0x49, 0);    /* Sample control */
-
-       gus_select_max_voices(24);
-
-       inb(u_Status);          /* Touch the status register */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       gus_reset();            /* Resets all voices */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       gus_write8(0x4c, 7);    /* Master reset | DAC enable | IRQ enable */
-
-       /*
-        * Set up for Digital ASIC
-        */
-
-       outb((0x05), gus_base + 0x0f);
-
-       mix_image |= 0x02;      /* Disable line out (for a moment) */
-       outb((mix_image), u_Mixer);
-
-       outb((0x00), u_IRQDMAControl);
-
-       outb((0x00), gus_base + 0x0f);
-
-       /*
-        * Now set up the DMA and IRQ interface
-        *
-        * The GUS supports two IRQs and two DMAs.
-        *
-        * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
-        * Adding this support requires significant changes to the dmabuf.c, dsp.c
-        * and audio.c also.
-        */
-
-       irq_image = 0;
-       tmp = gus_irq_map[gus_irq];
-       if (!gus_pnp_flag && !tmp)
-               printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
-       irq_image |= tmp;
-       irq_image |= 0x40;      /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
-
-       dual_dma_mode = 1;
-       if (gus_dma2 == gus_dma || gus_dma2 == -1)
-       {
-               dual_dma_mode = 0;
-               dma_image = 0x40;       /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
-
-               tmp = gus_dma_map[gus_dma];
-               if (!tmp)
-                       printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-               dma_image |= tmp;
-       }
-       else
-       {
-               /* Setup dual DMA channel mode for GUS MAX */
-
-               dma_image = gus_dma_map[gus_dma];
-               if (!dma_image)
-                       printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-               tmp = gus_dma_map[gus_dma2] << 3;
-               if (!tmp)
-               {
-                       printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
-                       tmp = 0x40;             /* Combine DMA channels */
-                           dual_dma_mode = 0;
-               }
-               dma_image |= tmp;
-       }
-
-       /*
-        * For some reason the IRQ and DMA addresses must be written twice
-        */
-
-       /*
-        * Doing it first time
-        */
-
-       outb((mix_image), u_Mixer);     /* Select DMA control */
-       outb((dma_image | 0x80), u_IRQDMAControl);      /* Set DMA address */
-
-       outb((mix_image | 0x40), u_Mixer);      /* Select IRQ control */
-       outb((irq_image), u_IRQDMAControl);     /* Set IRQ address */
-
-       /*
-        * Doing it second time
-        */
-
-       outb((mix_image), u_Mixer);     /* Select DMA control */
-       outb((dma_image), u_IRQDMAControl);     /* Set DMA address */
-
-       outb((mix_image | 0x40), u_Mixer);      /* Select IRQ control */
-       outb((irq_image), u_IRQDMAControl);     /* Set IRQ address */
-
-       gus_select_voice(0);    /* This disables writes to IRQ/DMA reg */
-
-       mix_image &= ~0x02;     /* Enable line out */
-       mix_image |= 0x08;      /* Enable IRQ */
-       outb((mix_image), u_Mixer);     /*
-                                        * Turn mixer channels on
-                                        * Note! Mic in is left off.
-                                        */
-
-       gus_select_voice(0);    /* This disables writes to IRQ/DMA reg */
-
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-
-       inb(u_Status);          /* Touch the status register */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       if (iw_mode)
-               gus_write8(0x19, gus_read8(0x19) | 0x01);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-
-static void __init pnp_mem_init(void)
-{
-#include "iwmem.h"
-#define CHUNK_SIZE (256*1024)
-#define BANK_SIZE (4*1024*1024)
-#define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
-
-       int bank, chunk, addr, total = 0;
-       int bank_sizes[4];
-       int i, j, bits = -1, testbits = -1, nbanks = 0;
-
-       /*
-        * This routine determines what kind of RAM is installed in each of the four
-        * SIMM banks and configures the DRAM address decode logic accordingly.
-        */
-
-       /*
-        *    Place the chip into enhanced mode
-        */
-       gus_write8(0x19, gus_read8(0x19) | 0x01);
-       gus_write8(0x53, gus_look8(0x53) & ~0x02);      /* Select DRAM I/O access */
-
-       /*
-        * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
-        */
-
-       gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c);
-
-       /*
-        * Perform the DRAM size detection for each bank individually.
-        */
-       for (bank = 0; bank < 4; bank++)
-       {
-               int size = 0;
-
-               addr = bank * BANK_SIZE;
-
-               /* Clean check points of each chunk */
-               for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-               {
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-               }
-
-               /* Write a value to each chunk point and verify the result */
-               for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-               {
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
-
-                       if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
-                               gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
-                       {
-                               /* OK. There is RAM. Now check for possible shadows */
-                               int ok = 1, chunk2;
-
-                               for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
-                                       if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
-                                                       gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
-                                               ok = 0; /* Addressing wraps */
-
-                               if (ok)
-                                       size = (chunk + 1) * CHUNK_SIZE;
-                       }
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-               }
-               bank_sizes[bank] = size;
-               if (size)
-                       nbanks = bank + 1;
-               DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
-       }
-
-       if (nbanks == 0)        /* No RAM - Give up */
-       {
-               printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
-               printk(KERN_ERR "Sound: Unable to work with this card.\n");
-               gus_write8(0x19, gus_read8(0x19) & ~0x01);
-               gus_mem_size = 0;
-               return;
-       }
-
-       /*
-        * Now we know how much DRAM there is in each bank. The next step is
-        * to find a DRAM size encoding (0 to 12) which is best for the combination
-        * we have.
-        *
-        * First try if any of the possible alternatives matches exactly the amount
-        * of memory we have.
-        */
-
-       for (i = 0; bits == -1 && i < 13; i++)
-       {
-               bits = i;
-
-               for (j = 0; bits != -1 && j < 4; j++)
-                       if (mem_decode[i][j] != bank_sizes[j])
-                               bits = -1;      /* No hit */
-       }
-
-       /*
-        * If necessary, try to find a combination where other than the last
-        * bank matches our configuration and the last bank is left oversized.
-        * In this way we don't leave holes in the middle of memory.
-        */
-
-       if (bits == -1)         /* No luck yet */
-       {
-               for (i = 0; bits == -1 && i < 13; i++)
-               {
-                       bits = i;
-
-                       for (j = 0; bits != -1 && j < nbanks - 1; j++)
-                               if (mem_decode[i][j] != bank_sizes[j])
-                                       bits = -1;      /* No hit */
-                       if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
-                               bits = -1;      /* The last bank is too small */
-               }
-       }
-       /*
-        * The last resort is to search for a combination where the banks are
-        * smaller than the actual SIMMs. This leaves some memory in the banks
-        * unused but doesn't leave holes in the DRAM address space.
-        */
-       if (bits == -1)         /* No luck yet */
-       {
-               for (i = 0; i < 13; i++)
-               {
-                       testbits = i;
-                       for (j = 0; testbits != -1 && j < nbanks - 1; j++)
-                               if (mem_decode[i][j] > bank_sizes[j]) {
-                                       testbits = -1;
-                               }
-                       if(testbits > bits) bits = testbits;
-               }
-               if (bits != -1)
-               {
-                       printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
-                       printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
-               }
-               printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
-               printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
-               bits = 0;
-       }
-       DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
-
-       for (bank = 0; bank < 4; bank++)
-       {
-               DDB(printk("  Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
-
-               if (bank_sizes[bank] > mem_decode[bits][bank])
-                       total += mem_decode[bits][bank];
-               else
-                       total += bank_sizes[bank];
-       }
-
-       DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-
-       /*
-        *    Set the memory addressing mode.
-        */
-       gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
-
-/*      Leave the chip into enhanced mode. Disable LFO  */
-       gus_mem_size = total;
-       iw_mode = 1;
-       gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
-}
-
-int __init gus_wave_detect(int baseaddr)
-{
-       unsigned long   i, max_mem = 1024L;
-       unsigned long   loc;
-       unsigned char   val;
-
-       if (!request_region(baseaddr, 16, "GUS"))
-               return 0;
-       if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */
-               release_region(baseaddr, 16);
-               return 0;
-       }
-
-       gus_base = baseaddr;
-
-       gus_write8(0x4c, 0);    /* Reset GF1 */
-       gus_delay();
-       gus_delay();
-
-       gus_write8(0x4c, 1);    /* Release Reset */
-       gus_delay();
-       gus_delay();
-
-#ifdef GUSPNP_AUTODETECT
-       val = gus_look8(0x5b);  /* Version number register */
-       gus_write8(0x5b, ~val); /* Invert all bits */
-
-       if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0))   /* No change */
-       {
-               if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f))        /* Change */
-               {
-                       DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
-                       gus_pnp_flag = 1;
-               }
-               else
-               {
-                       DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
-                       gus_pnp_flag = 0;
-               }
-       }
-       gus_write8(0x5b, val);  /* Restore all bits */
-#endif
-
-       if (gus_pnp_flag)
-               pnp_mem_init();
-       if (iw_mode)
-               return 1;
-
-       /* See if there is first block there.... */
-       gus_poke(0L, 0xaa);
-       if (gus_peek(0L) != 0xaa) {
-               release_region(baseaddr + 0x100, 12);
-               release_region(baseaddr, 16);
-               return 0;
-       }
-
-       /* Now zero it out so that I can check for mirroring .. */
-       gus_poke(0L, 0x00);
-       for (i = 1L; i < max_mem; i++)
-       {
-               int n, failed;
-
-               /* check for mirroring ... */
-               if (gus_peek(0L) != 0)
-                       break;
-               loc = i << 10;
-
-               for (n = loc - 1, failed = 0; n <= loc; n++)
-               {
-                       gus_poke(loc, 0xaa);
-                       if (gus_peek(loc) != 0xaa)
-                               failed = 1;
-                       gus_poke(loc, 0x55);
-                       if (gus_peek(loc) != 0x55)
-                               failed = 1;
-               }
-               if (failed)
-                       break;
-       }
-       gus_mem_size = i << 10;
-       return 1;
-}
-
-static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-
-       switch (cmd) 
-       {
-               case SNDCTL_SYNTH_INFO:
-                       gus_info.nr_voices = nr_voices;
-                       if (copy_to_user(arg, &gus_info, sizeof(gus_info)))
-                               return -EFAULT;
-                       return 0;
-
-               case SNDCTL_SEQ_RESETSAMPLES:
-                       reset_sample_memory();
-                       return 0;
-
-               case SNDCTL_SEQ_PERCMODE:
-                       return 0;
-
-               case SNDCTL_SYNTH_MEMAVL:
-                       return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
-
-               default:
-                       return -EINVAL;
-       }
-}
-
-static int guswave_set_instr(int dev, int voice, int instr_no)
-{
-       int sample_no;
-
-       if (instr_no < 0 || instr_no > MAX_PATCH)
-               instr_no = 0;   /* Default to acoustic piano */
-
-       if (voice < 0 || voice > 31)
-               return -EINVAL;
-
-       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-       {
-               voices[voice].sample_pending = instr_no;
-               return 0;
-       }
-       sample_no = patch_table[instr_no];
-       patch_map[voice] = -1;
-
-       if (sample_no == NOT_SAMPLE)
-       {
-/*             printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
-               return -EINVAL; /* Patch not defined */
-       }
-       if (sample_ptrs[sample_no] == -1)       /* Sample not loaded */
-       {
-/*             printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
-               return -EINVAL;
-       }
-       sample_map[voice] = sample_no;
-       patch_map[voice] = instr_no;
-       return 0;
-}
-
-static int guswave_kill_note(int dev, int voice, int note, int velocity)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       /* voice_alloc->map[voice] = 0xffff; */
-       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-       {
-               voices[voice].kill_pending = 1;
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       else
-       {
-               spin_unlock_irqrestore(&gus_lock,flags);
-               gus_voice_fade(voice);
-       }
-
-       return 0;
-}
-
-static void guswave_aftertouch(int dev, int voice, int pressure)
-{
-}
-
-static void guswave_panning(int dev, int voice, int value)
-{
-       if (voice >= 0 || voice < 32)
-               voices[voice].panning = value;
-}
-
-static void guswave_volume_method(int dev, int mode)
-{
-       if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
-               volume_method = mode;
-}
-
-static void compute_volume(int voice, int volume)
-{
-       if (volume < 128)
-               voices[voice].midi_volume = volume;
-
-       switch (volume_method)
-       {
-               case VOL_METHOD_ADAGIO:
-                       voices[voice].initial_volume =
-                               gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
-                                       voices[voice].expression_vol,
-                                       voices[voice].patch_vol);
-                       break;
-
-               case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
-                       voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
-                       break;
-
-               default:
-                       voices[voice].initial_volume = volume_base +
-                               (voices[voice].midi_volume * volume_scale);
-       }
-
-       if (voices[voice].initial_volume > 4030)
-               voices[voice].initial_volume = 4030;
-}
-
-static void compute_and_set_volume(int voice, int volume, int ramp_time)
-{
-       int curr, target, rate;
-       unsigned long flags;
-
-       compute_volume(voice, volume);
-       voices[voice].current_volume = voices[voice].initial_volume;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       /*
-        * CAUTION! Interrupts disabled. Enable them before returning
-        */
-
-       gus_select_voice(voice);
-
-       curr = gus_read16(0x09) >> 4;
-       target = voices[voice].initial_volume;
-
-       if (ramp_time == INSTANT_RAMP)
-       {
-               gus_rampoff();
-               gus_voice_volume(target);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       if (ramp_time == FAST_RAMP)
-               rate = 63;
-       else
-               rate = 16;
-       gus_ramp_rate(0, rate);
-
-       if ((target - curr) / 64 == 0)  /* Close enough to target. */
-       {
-               gus_rampoff();
-               gus_voice_volume(target);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       if (target > curr)
-       {
-               if (target > (4095 - 65))
-                       target = 4095 - 65;
-               gus_ramp_range(curr, target);
-               gus_rampon(0x00);       /* Ramp up, once, no IRQ */
-       }
-       else
-       {
-               if (target < 65)
-                       target = 65;
-
-               gus_ramp_range(target, curr);
-               gus_rampon(0x40);       /* Ramp down, once, no irq */
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void dynamic_volume_change(int voice)
-{
-       unsigned char status;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       status = gus_read8(0x00);       /* Get voice status */
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (status & 0x03)
-               return;         /* Voice was not running */
-
-       if (!(voices[voice].mode & WAVE_ENVELOPES))
-       {
-               compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-               return;
-       }
-       
-       /*
-        * Voice is running and has envelopes.
-        */
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       status = gus_read8(0x0d);       /* Ramping status */
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (status & 0x03)      /* Sustain phase? */
-       {
-               compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-               return;
-       }
-       if (voices[voice].env_phase < 0)
-               return;
-
-       compute_volume(voice, voices[voice].midi_volume);
-
-}
-
-static void guswave_controller(int dev, int voice, int ctrl_num, int value)
-{
-       unsigned long   flags;
-       unsigned long   freq;
-
-       if (voice < 0 || voice > 31)
-               return;
-
-       switch (ctrl_num)
-       {
-               case CTRL_PITCH_BENDER:
-                       voices[voice].bender = value;
-
-                       if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                       {
-                               freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
-                               voices[voice].current_freq = freq;
-
-                               spin_lock_irqsave(&gus_lock,flags);
-                               gus_select_voice(voice);
-                               gus_voice_freq(freq);
-                               spin_unlock_irqrestore(&gus_lock,flags);
-                       }
-                       break;
-
-               case CTRL_PITCH_BENDER_RANGE:
-                       voices[voice].bender_range = value;
-                       break;
-               case CTL_EXPRESSION:
-                       value /= 128;
-               case CTRL_EXPRESSION:
-                       if (volume_method == VOL_METHOD_ADAGIO)
-                       {
-                               voices[voice].expression_vol = value;
-                               if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                                       dynamic_volume_change(voice);
-                       }
-                       break;
-
-               case CTL_PAN:
-                       voices[voice].panning = (value * 2) - 128;
-                       break;
-
-               case CTL_MAIN_VOLUME:
-                       value = (value * 100) / 16383;
-
-               case CTRL_MAIN_VOLUME:
-                       voices[voice].main_vol = value;
-                       if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                               dynamic_volume_change(voice);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-static int guswave_start_note2(int dev, int voice, int note_num, int volume)
-{
-       int sample, best_sample, best_delta, delta_freq;
-       int is16bits, samplep, patch, pan;
-       unsigned long   note_freq, base_note, freq, flags;
-       unsigned char   mode = 0;
-
-       if (voice < 0 || voice > 31)
-       {
-/*             printk("GUS: Invalid voice\n");*/
-               return -EINVAL;
-       }
-       if (note_num == 255)
-       {
-               if (voices[voice].mode & WAVE_ENVELOPES)
-               {
-                       voices[voice].midi_volume = volume;
-                       dynamic_volume_change(voice);
-                       return 0;
-               }
-               compute_and_set_volume(voice, volume, 1);
-               return 0;
-       }
-       if ((patch = patch_map[voice]) == -1)
-               return -EINVAL;
-       if ((samplep = patch_table[patch]) == NOT_SAMPLE)
-       {
-               return -EINVAL;
-       }
-       note_freq = note_to_freq(note_num);
-
-       /*
-        * Find a sample within a patch so that the note_freq is between low_note
-        * and high_note.
-        */
-       sample = -1;
-
-       best_sample = samplep;
-       best_delta = 1000000;
-       while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1)
-       {
-               delta_freq = note_freq - samples[samplep].base_note;
-               if (delta_freq < 0)
-                       delta_freq = -delta_freq;
-               if (delta_freq < best_delta)
-               {
-                       best_sample = samplep;
-                       best_delta = delta_freq;
-               }
-               if (samples[samplep].low_note <= note_freq &&
-                       note_freq <= samples[samplep].high_note)
-               {
-                       sample = samplep;
-               }
-               else
-                       samplep = samples[samplep].key; /* Link to next sample */
-         }
-       if (sample == -1)
-               sample = best_sample;
-
-       if (sample == -1)
-       {
-/*             printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/
-               return 0;       /* Should play default patch ??? */
-       }
-       is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
-       voices[voice].mode = samples[sample].mode;
-       voices[voice].patch_vol = samples[sample].volume;
-
-       if (iw_mode)
-               gus_write8(0x15, 0x00);         /* RAM, Reset voice deactivate bit of SMSI */
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               int i;
-
-               for (i = 0; i < 6; i++)
-               {
-                       voices[voice].env_rate[i] = samples[sample].env_rate[i];
-                       voices[voice].env_offset[i] = samples[sample].env_offset[i];
-               }
-       }
-       sample_map[voice] = sample;
-
-       if (voices[voice].fixed_pitch)  /* Fixed pitch */
-       {
-                 freq = samples[sample].base_freq;
-       }
-       else
-       {
-               base_note = samples[sample].base_note / 100;
-               note_freq /= 100;
-
-               freq = samples[sample].base_freq * note_freq / base_note;
-       }
-
-       voices[voice].orig_freq = freq;
-
-       /*
-        * Since the pitch bender may have been set before playing the note, we
-        * have to calculate the bending now.
-        */
-
-       freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender,
-                               voices[voice].bender_range, 0);
-       voices[voice].current_freq = freq;
-
-       pan = (samples[sample].panning + voices[voice].panning) / 32;
-       pan += 7;
-       if (pan < 0)
-               pan = 0;
-       if (pan > 15)
-               pan = 15;
-
-       if (samples[sample].mode & WAVE_16_BITS)
-       {
-               mode |= 0x04;   /* 16 bits */
-               if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
-                       ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
-                               printk(KERN_ERR "GUS: Sample address error\n");
-       }
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_off();
-       gus_rampoff();
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               compute_volume(voice, volume);
-               init_envelope(voice);
-       }
-       else
-       {
-               compute_and_set_volume(voice, volume, 0);
-       }
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       if (samples[sample].mode & WAVE_LOOP_BACK)
-               gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
-                       voices[voice].offset_pending, 0, is16bits);     /* start=end */
-       else
-               gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits);  /* Sample start=begin */
-
-       if (samples[sample].mode & WAVE_LOOPING)
-       {
-               mode |= 0x08;
-
-               if (samples[sample].mode & WAVE_BIDIR_LOOP)
-                       mode |= 0x10;
-
-               if (samples[sample].mode & WAVE_LOOP_BACK)
-               {
-                       gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end -
-                                          voices[voice].offset_pending,
-                                          (samples[sample].fractions >> 4) & 0x0f, is16bits);
-                       mode |= 0x40;
-               }
-               gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
-                       samples[sample].fractions & 0x0f, is16bits);    /* Loop start location */
-               gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
-                       (samples[sample].fractions >> 4) & 0x0f, is16bits);     /* Loop end location */
-       }
-       else
-       {
-               mode |= 0x20;   /* Loop IRQ at the end */
-               voices[voice].loop_irq_mode = LMODE_FINISH;     /* Ramp down at the end */
-               voices[voice].loop_irq_parm = 1;
-               gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits); /* Loop start location */
-               gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
-                       (samples[sample].fractions >> 4) & 0x0f, is16bits);     /* Loop end location */
-       }
-       gus_voice_freq(freq);
-       gus_voice_balance(pan);
-       gus_voice_on(mode);
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       return 0;
-}
-
-/*
- * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
- * when the note playing on the voice is changed.  It uses volume
- * ramping.
- */
-
-static int guswave_start_note(int dev, int voice, int note_num, int volume)
-{
-       unsigned long flags;
-       int mode;
-       int ret_val = 0;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       if (note_num == 255)
-       {
-               if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-               {
-                       voices[voice].volume_pending = volume;
-               }
-               else
-               {
-                       ret_val = guswave_start_note2(dev, voice, note_num, volume);
-               }
-       }
-       else
-       {
-               gus_select_voice(voice);
-               mode = gus_read8(0x00);
-               if (mode & 0x20)
-                       gus_write8(0x00, mode & 0xdf);  /* No interrupt! */
-
-               voices[voice].offset_pending = 0;
-               voices[voice].kill_pending = 0;
-               voices[voice].volume_irq_mode = 0;
-               voices[voice].loop_irq_mode = 0;
-
-               if (voices[voice].sample_pending >= 0)
-               {
-                       spin_unlock_irqrestore(&gus_lock,flags);        /* Run temporarily with interrupts enabled */
-                       guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
-                       voices[voice].sample_pending = -1;
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);        /* Reselect the voice (just to be sure) */
-               }
-               if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
-               {
-                       ret_val = guswave_start_note2(dev, voice, note_num, volume);
-               }
-               else
-               {
-                       voices[voice].dev_pending = dev;
-                       voices[voice].note_pending = note_num;
-                       voices[voice].volume_pending = volume;
-                       voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
-                       gus_rampoff();
-                       gus_ramp_range(2000, 4065);
-                       gus_ramp_rate(0, 63);   /* Fastest possible rate */
-                       gus_rampon(0x20 | 0x40);        /* Ramp down, once, irq */
-               }
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return ret_val;
-}
-
-static void guswave_reset(int dev)
-{
-       int i;
-
-       for (i = 0; i < 32; i++)
-       {
-               gus_voice_init(i);
-               gus_voice_init2(i);
-       }
-}
-
-static int guswave_open(int dev, int mode)
-{
-       int err;
-
-       if (gus_busy)
-               return -EBUSY;
-
-       voice_alloc->timestamp = 0;
-
-       if (gus_no_wave_dma) {
-               gus_no_dma = 1;
-       } else {
-               if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
-               {
-                       /* printk( "GUS: Loading samples without DMA\n"); */
-                       gus_no_dma = 1; /* Upload samples using PIO */
-               }
-               else
-                       gus_no_dma = 0;
-       }
-
-       init_waitqueue_head(&dram_sleeper);
-       gus_busy = 1;
-       active_device = GUS_DEV_WAVE;
-
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-       gus_initialize();
-       gus_reset();
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-
-       return 0;
-}
-
-static void guswave_close(int dev)
-{
-       gus_busy = 0;
-       active_device = 0;
-       gus_reset();
-
-       if (!gus_no_dma)
-               DMAbuf_close_dma(gus_devnum);
-}
-
-static int guswave_load_patch(int dev, int format, const char __user *addr,
-                  int offs, int count, int pmgr_flag)
-{
-       struct patch_info patch;
-       int instr;
-       long sizeof_patch;
-
-       unsigned long blk_sz, blk_end, left, src_offs, target;
-
-       sizeof_patch = (long) &patch.data[0] - (long) &patch;   /* Header size */
-
-       if (format != GUS_PATCH)
-       {
-/*             printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/
-               return -EINVAL;
-       }
-       if (count < sizeof_patch)
-       {
-/*               printk("GUS Error: Patch header too short\n");*/
-                 return -EINVAL;
-       }
-       count -= sizeof_patch;
-
-       if (free_sample >= MAX_SAMPLE)
-       {
-/*               printk("GUS: Sample table full\n");*/
-                 return -ENOSPC;
-       }
-       /*
-        * Copy the header from user space but ignore the first bytes which have
-        * been transferred already.
-        */
-
-       if (copy_from_user(&((char *) &patch)[offs], &(addr)[offs],
-                          sizeof_patch - offs))
-               return -EFAULT;
-
-       if (patch.mode & WAVE_ROM)
-               return -EINVAL;
-       if (gus_mem_size == 0)
-               return -ENOSPC;
-
-       instr = patch.instr_no;
-
-       if (instr < 0 || instr > MAX_PATCH)
-       {
-/*             printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/
-               return -EINVAL;
-       }
-       if (count < patch.len)
-       {
-/*             printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/
-               patch.len = count;
-       }
-       if (patch.len <= 0 || patch.len > gus_mem_size)
-       {
-/*             printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/
-               return -EINVAL;
-       }
-       if (patch.mode & WAVE_LOOPING)
-       {
-               if (patch.loop_start < 0 || patch.loop_start >= patch.len)
-               {
-/*                     printk(KERN_ERR "GUS: Invalid loop start\n");*/
-                       return -EINVAL;
-               }
-               if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
-               {
-/*                     printk(KERN_ERR "GUS: Invalid loop end\n");*/
-                       return -EINVAL;
-               }
-       }
-       free_mem_ptr = (free_mem_ptr + 31) & ~31;       /* 32 byte alignment */
-
-       if (patch.mode & WAVE_16_BITS)
-       {
-               /*
-                * 16 bit samples must fit one 256k bank.
-                */
-               if (patch.len >= GUS_BANK_SIZE)
-               {
-/*                      printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/
-                       return -ENOSPC;
-               }
-               if ((free_mem_ptr / GUS_BANK_SIZE) !=
-                       ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
-               {
-                       unsigned long   tmp_mem =       
-                               /* Align to 256K */
-                                       ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
-
-                       if ((tmp_mem + patch.len) > gus_mem_size)
-                               return -ENOSPC;
-
-                       free_mem_ptr = tmp_mem;         /* This leaves unusable memory */
-               }
-       }
-       if ((free_mem_ptr + patch.len) > gus_mem_size)
-               return -ENOSPC;
-
-       sample_ptrs[free_sample] = free_mem_ptr;
-
-       /*
-        * Tremolo is not possible with envelopes
-        */
-
-       if (patch.mode & WAVE_ENVELOPES)
-               patch.mode &= ~WAVE_TREMOLO;
-
-       if (!(patch.mode & WAVE_FRACTIONS))
-       {
-                 patch.fractions = 0;
-       }
-       memcpy((char *) &samples[free_sample], &patch, sizeof_patch);
-
-       /*
-        * Link this_one sample to the list of samples for patch 'instr'.
-        */
-
-       samples[free_sample].key = patch_table[instr];
-       patch_table[instr] = free_sample;
-
-       /*
-        * Use DMA to transfer the wave data to the DRAM
-        */
-
-       left = patch.len;
-       src_offs = 0;
-       target = free_mem_ptr;
-
-       while (left)            /* Not completely transferred yet */
-       {
-               blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
-               if (blk_sz > left)
-                       blk_sz = left;
-
-               /*
-                * DMA cannot cross bank (256k) boundaries. Check for that.
-                */
-                
-               blk_end = target + blk_sz;
-
-               if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
-               {
-                       /* Split the block */
-                       blk_end &= ~(GUS_BANK_SIZE - 1);
-                       blk_sz = blk_end - target;
-               }
-               if (gus_no_dma)
-               {
-                       /*
-                        * For some reason the DMA is not possible. We have to use PIO.
-                        */
-                       long i;
-                       unsigned char data;
-
-                       for (i = 0; i < blk_sz; i++)
-                       {
-                               get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[sizeof_patch + i]));
-                               if (patch.mode & WAVE_UNSIGNED)
-                                       if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
-                                               data ^= 0x80;   /* Convert to signed */
-                               gus_poke(target + i, data);
-                       }
-               }
-               else
-               {
-                       unsigned long address, hold_address;
-                       unsigned char dma_command;
-                       unsigned long flags;
-
-                       if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
-                       {
-                               printk(KERN_ERR "GUS: DMA buffer == NULL\n");
-                               return -ENOSPC;
-                       }
-                       /*
-                        * OK, move now. First in and then out.
-                        */
-
-                       if (copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf,
-                                          &(addr)[sizeof_patch + src_offs],
-                                          blk_sz))
-                               return -EFAULT;
-
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                       DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
-                               blk_sz, DMA_MODE_WRITE);
-
-                       /*
-                        * Set the DRAM address for the wave data
-                        */
-
-                       if (iw_mode)
-                       {
-                               /* Different address translation in enhanced mode */
-
-                               unsigned char   hi;
-
-                               if (gus_dma > 4)
-                                       address = target >> 1;  /* Convert to 16 bit word address */
-                               else
-                                       address = target;
-
-                               hi = (unsigned char) ((address >> 16) & 0xf0);
-                               hi += (unsigned char) (address & 0x0f);
-
-                               gus_write16(0x42, (address >> 4) & 0xffff);     /* DMA address (low) */
-                               gus_write8(0x50, hi);
-                       }
-                       else
-                       {
-                               address = target;
-                               if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-                               {
-                                       hold_address = address;
-                                       address = address >> 1;
-                                       address &= 0x0001ffffL;
-                                       address |= (hold_address & 0x000c0000L);
-                               }
-                               gus_write16(0x42, (address >> 4) & 0xffff);     /* DRAM DMA address */
-                       }
-
-                       /*
-                        * Start the DMA transfer
-                        */
-
-                       dma_command = 0x21;             /* IRQ enable, DMA start */
-                       if (patch.mode & WAVE_UNSIGNED)
-                               dma_command |= 0x80;    /* Invert MSB */
-                       if (patch.mode & WAVE_16_BITS)
-                               dma_command |= 0x40;    /* 16 bit _DATA_ */
-                       if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-                               dma_command |= 0x04;    /* 16 bit DMA _channel_ */
-                       
-                       /*
-                        * Sleep here until the DRAM DMA done interrupt is served
-                        */
-                       active_device = GUS_DEV_WAVE;
-                       gus_write8(0x41, dma_command);  /* Lets go luteet (=bugs) */
-
-                       spin_unlock_irqrestore(&gus_lock,flags); /* opens a race */
-                       if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ))
-                               printk("GUS: DMA Transfer timed out\n");
-               }
-
-               /*
-                * Now the next part
-                */
-
-               left -= blk_sz;
-               src_offs += blk_sz;
-               target += blk_sz;
-
-               gus_write8(0x41, 0);    /* Stop DMA */
-       }
-
-       free_mem_ptr += patch.len;
-       free_sample++;
-       return 0;
-}
-
-static void guswave_hw_control(int dev, unsigned char *event_rec)
-{
-       int voice, cmd;
-       unsigned short p1, p2;
-       unsigned int plong;
-       unsigned long flags;
-
-       cmd = event_rec[2];
-       voice = event_rec[3];
-       p1 = *(unsigned short *) &event_rec[4];
-       p2 = *(unsigned short *) &event_rec[6];
-       plong = *(unsigned int *) &event_rec[4];
-
-       if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
-               (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
-               do_volume_irq(voice);
-
-       switch (cmd)
-       {
-               case _GUS_NUMVOICES:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_select_max_voices(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICESAMPLE:
-                       guswave_set_instr(dev, voice, p1);
-                       break;
-
-               case _GUS_VOICEON:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_voice_on(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEOFF:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_off();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEFADE:
-                       gus_voice_fade(voice);
-                       break;
-
-               case _GUS_VOICEMODE:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_voice_mode(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEBALA:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_balance(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEFREQ:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_freq(plong);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEVOL:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_volume(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEVOL2:    /* Just update the software voice level */
-                       voices[voice].initial_volume = voices[voice].current_volume = p1;
-                       break;
-
-               case _GUS_RAMPRANGE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NO-NO */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_ramp_range(p1, p2);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPRATE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NJET-NJET */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_ramp_rate(p1, p2);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPMODE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NO-NO */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_ramp_mode(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPON:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* EI-EI */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_rampon(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPOFF:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NEJ-NEJ */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_rampoff();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOLUME_SCALE:
-                       volume_base = p1;
-                       volume_scale = p2;
-                       break;
-
-               case _GUS_VOICE_POS:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_set_voice_pos(voice, plong);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-static int gus_audio_set_speed(int speed)
-{
-       if (speed <= 0)
-               speed = gus_audio_speed;
-
-       if (speed < 4000)
-               speed = 4000;
-
-       if (speed > 44100)
-               speed = 44100;
-
-       gus_audio_speed = speed;
-
-       if (only_read_access)
-       {
-               /* Compute nearest valid recording speed  and return it */
-
-               /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
-               speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-               speed = (9878400 / (speed * 16)) - 2;
-       }
-       return speed;
-}
-
-static int gus_audio_set_channels(int channels)
-{
-       if (!channels)
-               return gus_audio_channels;
-       if (channels > 2)
-               channels = 2;
-       if (channels < 1)
-               channels = 1;
-       gus_audio_channels = channels;
-       return channels;
-}
-
-static int gus_audio_set_bits(int bits)
-{
-       if (!bits)
-               return gus_audio_bits;
-
-       if (bits != 8 && bits != 16)
-               bits = 8;
-
-       if (only_8_bits)
-               bits = 8;
-
-       gus_audio_bits = bits;
-       return bits;
-}
-
-static int gus_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int val;
-
-       switch (cmd) 
-       {
-               case SOUND_PCM_WRITE_RATE:
-                       if (get_user(val, (int __user*)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_speed(val);
-                       break;
-
-               case SOUND_PCM_READ_RATE:
-                       val = gus_audio_speed;
-                       break;
-
-               case SNDCTL_DSP_STEREO:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_channels(val + 1) - 1;
-                       break;
-
-               case SOUND_PCM_WRITE_CHANNELS:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_channels(val);
-                       break;
-
-               case SOUND_PCM_READ_CHANNELS:
-                       val = gus_audio_channels;
-                       break;
-               
-               case SNDCTL_DSP_SETFMT:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_bits(val);
-                       break;
-               
-               case SOUND_PCM_READ_BITS:
-                       val = gus_audio_bits;
-                       break;
-               
-               case SOUND_PCM_WRITE_FILTER:            /* NOT POSSIBLE */
-               case SOUND_PCM_READ_FILTER:
-                       val = -EINVAL;
-                       break;
-               default:
-                       return -EINVAL;
-       }
-       return put_user(val, (int __user *)arg);
-}
-
-static void gus_audio_reset(int dev)
-{
-       if (recording_active)
-       {
-               gus_write8(0x49, 0x00); /* Halt recording */
-               set_input_volumes();
-       }
-}
-
-static int saved_iw_mode;      /* A hack hack hack */
-
-static int gus_audio_open(int dev, int mode)
-{
-       if (gus_busy)
-               return -EBUSY;
-
-       if (gus_pnp_flag && mode & OPEN_READ)
-       {
-/*             printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/
-               return -EIO;
-       }
-       gus_initialize();
-
-       gus_busy = 1;
-       active_device = 0;
-
-       saved_iw_mode = iw_mode;
-       if (iw_mode)
-       {
-               /* There are some problems with audio in enhanced mode so disable it */
-               gus_write8(0x19, gus_read8(0x19) & ~0x01);      /* Disable enhanced mode */
-               iw_mode = 0;
-       }
-
-       gus_reset();
-       reset_sample_memory();
-       gus_select_max_voices(14);
-
-       pcm_active = 0;
-       dma_active = 0;
-       pcm_opened = 1;
-       if (mode & OPEN_READ)
-       {
-               recording_active = 1;
-               set_input_volumes();
-       }
-       only_read_access = !(mode & OPEN_WRITE);
-       only_8_bits = mode & OPEN_READ;
-       if (only_8_bits)
-               audio_devs[dev]->format_mask = AFMT_U8;
-       else
-               audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
-
-       return 0;
-}
-
-static void gus_audio_close(int dev)
-{
-       iw_mode = saved_iw_mode;
-       gus_reset();
-       gus_busy = 0;
-       pcm_opened = 0;
-       active_device = 0;
-
-       if (recording_active)
-       {
-               gus_write8(0x49, 0x00); /* Halt recording */
-               set_input_volumes();
-       }
-       recording_active = 0;
-}
-
-static void gus_audio_update_volume(void)
-{
-       unsigned long flags;
-       int voice;
-
-       if (pcm_active && pcm_opened)
-               for (voice = 0; voice < gus_audio_channels; voice++)
-               {
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_rampoff();
-                       gus_voice_volume(1530 + (25 * gus_pcm_volume));
-                       gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-                       spin_unlock_irqrestore(&gus_lock,flags);
-               }
-}
-
-static void play_next_pcm_block(void)
-{
-       unsigned long flags;
-       int speed = gus_audio_speed;
-       int this_one, is16bits, chn;
-       unsigned long dram_loc;
-       unsigned char mode[2], ramp_mode[2];
-
-       if (!pcm_qlen)
-               return;
-
-       this_one = pcm_head;
-
-       for (chn = 0; chn < gus_audio_channels; chn++)
-       {
-               mode[chn] = 0x00;
-               ramp_mode[chn] = 0x03;  /* Ramping and rollover off */
-
-               if (chn == 0)
-               {
-                       mode[chn] |= 0x20;      /* Loop IRQ */
-                       voices[chn].loop_irq_mode = LMODE_PCM;
-               }
-               if (gus_audio_bits != 8)
-               {
-                       is16bits = 1;
-                       mode[chn] |= 0x04;      /* 16 bit data */
-               }
-               else
-                       is16bits = 0;
-
-               dram_loc = this_one * pcm_bsize;
-               dram_loc += chn * pcm_banksize;
-
-               if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */
-               {
-                       mode[chn] |= 0x08;      /* Enable loop */
-                       ramp_mode[chn] = 0x03;  /* Disable rollover bit */
-               }
-               else
-               {
-                       if (chn == 0)
-                               ramp_mode[chn] = 0x04;  /* Enable rollover bit */
-               }
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(chn);
-               gus_voice_freq(speed);
-
-               if (gus_audio_channels == 1)
-                       gus_voice_balance(7);           /* mono */
-               else if (chn == 0)
-                       gus_voice_balance(0);           /* left */
-               else
-                       gus_voice_balance(15);          /* right */
-
-               if (!pcm_active)        /* Playback not already active */
-               {
-                       /*
-                        * The playback was not started yet (or there has been a pause).
-                        * Start the voice (again) and ask for a rollover irq at the end of
-                        * this_one block. If this_one one is last of the buffers, use just
-                        * the normal loop with irq.
-                        */
-
-                       gus_voice_off();
-                       gus_rampoff();
-                       gus_voice_volume(1530 + (25 * gus_pcm_volume));
-                       gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-
-                       gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits);  /* Starting position */
-                       gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits);  /* Loop start */
-
-                       if (chn != 0)
-                               gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
-                                                  0, is16bits);        /* Loop end location */
-               }
-               if (chn == 0)
-                       gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
-                                        0, is16bits);  /* Loop end location */
-               else
-                       mode[chn] |= 0x08;      /* Enable looping */
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       for (chn = 0; chn < gus_audio_channels; chn++)
-       {
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(chn);
-               gus_write8(0x0d, ramp_mode[chn]);
-               if (iw_mode)
-                       gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */
-               gus_voice_on(mode[chn]);
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       pcm_active = 1;
-}
-
-static void gus_transfer_output_block(int dev, unsigned long buf,
-                         int total_count, int intrflag, int chn)
-{
-       /*
-        * This routine transfers one block of audio data to the DRAM. In mono mode
-        * it's called just once. When in stereo mode, this_one routine is called
-        * once for both channels.
-        *
-        * The left/mono channel data is transferred to the beginning of dram and the
-        * right data to the area pointed by gus_page_size.
-        */
-
-       int this_one, count;
-       unsigned long flags;
-       unsigned char dma_command;
-       unsigned long address, hold_address;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       count = total_count / gus_audio_channels;
-
-       if (chn == 0)
-       {
-               if (pcm_qlen >= pcm_nblk)
-                       printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n");
-
-               this_one = pcm_current_block = pcm_tail;
-               pcm_qlen++;
-               pcm_tail = (pcm_tail + 1) % pcm_nblk;
-               pcm_datasize[this_one] = count;
-       }
-       else
-               this_one = pcm_current_block;
-
-       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-       DMAbuf_start_dma(dev, buf + (chn * count), count, DMA_MODE_WRITE);
-
-       address = this_one * pcm_bsize;
-       address += chn * pcm_banksize;
-
-       if (audio_devs[dev]->dmap_out->dma > 3)
-       {
-               hold_address = address;
-               address = address >> 1;
-               address &= 0x0001ffffL;
-               address |= (hold_address & 0x000c0000L);
-       }
-       gus_write16(0x42, (address >> 4) & 0xffff);     /* DRAM DMA address */
-
-       dma_command = 0x21;     /* IRQ enable, DMA start */
-
-       if (gus_audio_bits != 8)
-               dma_command |= 0x40;    /* 16 bit _DATA_ */
-       else
-               dma_command |= 0x80;    /* Invert MSB */
-
-       if (audio_devs[dev]->dmap_out->dma > 3)
-               dma_command |= 0x04;    /* 16 bit DMA channel */
-
-       gus_write8(0x41, dma_command);  /* Kick start */
-
-       if (chn == (gus_audio_channels - 1))    /* Last channel */
-       {
-               /*
-                * Last (right or mono) channel data
-                */
-               dma_active = 1; /* DMA started. There is a unacknowledged buffer */
-               active_device = GUS_DEV_PCM_DONE;
-               if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
-               {
-                       play_next_pcm_block();
-               }
-       }
-       else
-       {
-               /*
-                * Left channel data. The right channel
-                * is transferred after DMA interrupt
-                */
-               active_device = GUS_DEV_PCM_CONTINUE;
-       }
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_uninterleave8(char *buf, int l)
-{
-/* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */
-       int i, p = 0, halfsize = l / 2;
-       char *buf2 = buf + halfsize, *src = bounce_buf;
-
-       memcpy(bounce_buf, buf, l);
-
-       for (i = 0; i < halfsize; i++)
-       {
-               buf[i] = src[p++];      /* Left channel */
-               buf2[i] = src[p++];     /* Right channel */
-       }
-}
-
-static void gus_uninterleave16(short *buf, int l)
-{
-/* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */
-       int i, p = 0, halfsize = l / 2;
-       short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
-
-       memcpy(bounce_buf, (char *) buf, l * 2);
-
-       for (i = 0; i < halfsize; i++)
-       {
-               buf[i] = src[p++];      /* Left channel */
-               buf2[i] = src[p++];     /* Right channel */
-       }
-}
-
-static void gus_audio_output_block(int dev, unsigned long buf, int total_count,
-                      int intrflag)
-{
-       struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
-       dmap->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-
-       pcm_current_buf = buf;
-       pcm_current_count = total_count;
-       pcm_current_intrflag = intrflag;
-       pcm_current_dev = dev;
-       if (gus_audio_channels == 2)
-       {
-               char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
-
-               if (gus_audio_bits == 8)
-                       gus_uninterleave8(b, total_count);
-               else
-                       gus_uninterleave16((short *) b, total_count / 2);
-       }
-       gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
-}
-
-static void gus_audio_start_input(int dev, unsigned long buf, int count,
-                     int intrflag)
-{
-       unsigned long flags;
-       unsigned char mode;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
-       mode = 0xa0;            /* DMA IRQ enabled, invert MSB */
-
-       if (audio_devs[dev]->dmap_in->dma > 3)
-               mode |= 0x04;   /* 16 bit DMA channel */
-       if (gus_audio_channels > 1)
-               mode |= 0x02;   /* Stereo */
-       mode |= 0x01;           /* DMA enable */
-
-       gus_write8(0x49, mode);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
-       unsigned int rate;
-
-       gus_audio_bsize = bsize;
-       audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
-       rate = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-
-       gus_write8(0x48, rate & 0xff);  /* Set sampling rate */
-
-       if (gus_audio_bits != 8)
-       {
-/*             printk("GUS Error: 16 bit recording not supported\n");*/
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gus_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
-       int i;
-
-       long mem_ptr, mem_size;
-
-       audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-       mem_ptr = 0;
-       mem_size = gus_mem_size / gus_audio_channels;
-
-       if (mem_size > (256 * 1024))
-               mem_size = 256 * 1024;
-
-       pcm_bsize = bsize / gus_audio_channels;
-       pcm_head = pcm_tail = pcm_qlen = 0;
-
-       pcm_nblk = 2;           /* MAX_PCM_BUFFERS; */
-       if ((pcm_bsize * pcm_nblk) > mem_size)
-               pcm_nblk = mem_size / pcm_bsize;
-
-       for (i = 0; i < pcm_nblk; i++)
-               pcm_datasize[i] = 0;
-
-       pcm_banksize = pcm_nblk * pcm_bsize;
-
-       if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
-               pcm_nblk--;
-       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-       return 0;
-}
-
-static int gus_local_qlen(int dev)
-{
-       return pcm_qlen;
-}
-
-
-static struct audio_driver gus_audio_driver =
-{
-       .owner                  = THIS_MODULE,
-       .open                   = gus_audio_open,
-       .close                  = gus_audio_close,
-       .output_block           = gus_audio_output_block,
-       .start_input            = gus_audio_start_input,
-       .ioctl                  = gus_audio_ioctl,
-       .prepare_for_input      = gus_audio_prepare_for_input,
-       .prepare_for_output     = gus_audio_prepare_for_output,
-       .halt_io                = gus_audio_reset,
-       .local_qlen             = gus_local_qlen,
-};
-
-static void guswave_setup_voice(int dev, int voice, int chn)
-{
-       struct channel_info *info = &synth_devs[dev]->chn_info[chn];
-
-       guswave_set_instr(dev, voice, info->pgm_num);
-       voices[voice].expression_vol = info->controllers[CTL_EXPRESSION];       /* Just MSB */
-       voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
-       voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
-       voices[voice].bender = 0;
-       voices[voice].bender_range = info->bender_range;
-
-       if (chn == 9)
-               voices[voice].fixed_pitch = 1;
-}
-
-static void guswave_bender(int dev, int voice, int value)
-{
-       int freq;
-       unsigned long   flags;
-
-       voices[voice].bender = value - 8192;
-       freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
-       voices[voice].current_freq = freq;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_freq(freq);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-       int i, p, best = -1, best_time = 0x7fffffff;
-
-       p = alloc->ptr;
-       /*
-        * First look for a completely stopped voice
-        */
-
-       for (i = 0; i < alloc->max_voice; i++)
-       {
-               if (alloc->map[p] == 0)
-               {
-                       alloc->ptr = p;
-                       return p;
-               }
-               if (alloc->alloc_times[p] < best_time)
-               {
-                       best = p;
-                       best_time = alloc->alloc_times[p];
-               }
-               p = (p + 1) % alloc->max_voice;
-       }
-
-       /*
-        * Then look for a releasing voice
-        */
-
-       for (i = 0; i < alloc->max_voice; i++)
-       {
-               if (alloc->map[p] == 0xffff)
-               {
-                       alloc->ptr = p;
-                       return p;
-               }
-               p = (p + 1) % alloc->max_voice;
-       }
-       if (best >= 0)
-               p = best;
-
-       alloc->ptr = p;
-       return p;
-}
-
-static struct synth_operations guswave_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "GUS",
-       .info           = &gus_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_GUS,
-       .open           = guswave_open,
-       .close          = guswave_close,
-       .ioctl          = guswave_ioctl,
-       .kill_note      = guswave_kill_note,
-       .start_note     = guswave_start_note,
-       .set_instr      = guswave_set_instr,
-       .reset          = guswave_reset,
-       .hw_control     = guswave_hw_control,
-       .load_patch     = guswave_load_patch,
-       .aftertouch     = guswave_aftertouch,
-       .controller     = guswave_controller,
-       .panning        = guswave_panning,
-       .volume_method  = guswave_volume_method,
-       .bender         = guswave_bender,
-       .alloc_voice    = guswave_alloc,
-       .setup_voice    = guswave_setup_voice
-};
-
-static void set_input_volumes(void)
-{
-       unsigned long flags;
-       unsigned char mask = 0xff & ~0x06;      /* Just line out enabled */
-
-       if (have_gus_max)       /* Don't disturb GUS MAX */
-               return;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       /*
-        *    Enable channels having vol > 10%
-        *      Note! bit 0x01 means the line in DISABLED while 0x04 means
-        *            the mic in ENABLED.
-        */
-       if (gus_line_vol > 10)
-               mask &= ~0x01;
-       if (gus_mic_vol > 10)
-               mask |= 0x04;
-
-       if (recording_active)
-       {
-               /*
-                *    Disable channel, if not selected for recording
-                */
-               if (!(gus_recmask & SOUND_MASK_LINE))
-                       mask |= 0x01;
-               if (!(gus_recmask & SOUND_MASK_MIC))
-                       mask &= ~0x04;
-       }
-       mix_image &= ~0x07;
-       mix_image |= mask & 0x07;
-       outb((mix_image), u_Mixer);
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-#define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
-                        SOUND_MASK_SYNTH|SOUND_MASK_PCM)
-
-int gus_default_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int vol, val;
-
-       if (((cmd >> 8) & 0xff) != 'M')
-               return -EINVAL;
-
-       if (!access_ok(VERIFY_WRITE, arg, sizeof(int)))
-               return -EFAULT;
-
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE) 
-       {
-               if (__get_user(val, (int __user *) arg))
-                       return -EFAULT;
-
-               switch (cmd & 0xff) 
-               {
-                       case SOUND_MIXER_RECSRC:
-                               gus_recmask = val & MIX_DEVS;
-                               if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
-                                       gus_recmask = SOUND_MASK_MIC;
-                               /* Note! Input volumes are updated during next open for recording */
-                               val = gus_recmask;
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               vol = val & 0xff;
-                               if (vol < 0)
-                                       vol = 0;
-                               if (vol > 100)
-                                       vol = 100;
-                               gus_mic_vol = vol;
-                               set_input_volumes();
-                               val = vol | (vol << 8);
-                               break;
-                               
-                       case SOUND_MIXER_LINE:
-                               vol = val & 0xff;
-                               if (vol < 0)
-                                       vol = 0;
-                               if (vol > 100)
-                                       vol = 100;
-                               gus_line_vol = vol;
-                               set_input_volumes();
-                               val = vol | (vol << 8);
-                               break;
-
-                       case SOUND_MIXER_PCM:
-                               gus_pcm_volume = val & 0xff;
-                               if (gus_pcm_volume < 0)
-                                       gus_pcm_volume = 0;
-                               if (gus_pcm_volume > 100)
-                                       gus_pcm_volume = 100;
-                               gus_audio_update_volume();
-                               val = gus_pcm_volume | (gus_pcm_volume << 8);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               gus_wave_volume = val & 0xff;
-                               if (gus_wave_volume < 0)
-                                       gus_wave_volume = 0;
-                               if (gus_wave_volume > 100)
-                                       gus_wave_volume = 100;
-                               if (active_device == GUS_DEV_WAVE) 
-                               {
-                                       int voice;
-                                       for (voice = 0; voice < nr_voices; voice++)
-                                       dynamic_volume_change(voice);   /* Apply the new vol */
-                               }
-                               val = gus_wave_volume | (gus_wave_volume << 8);
-                               break;
-
-                       default:
-                               return -EINVAL;
-               }
-       }
-       else
-       {
-               switch (cmd & 0xff) 
-               {
-                       /*
-                        * Return parameters
-                        */
-                       case SOUND_MIXER_RECSRC:
-                               val = gus_recmask;
-                               break;
-                                       
-                       case SOUND_MIXER_DEVMASK:
-                               val = MIX_DEVS;
-                               break;
-
-                       case SOUND_MIXER_STEREODEVS:
-                               val = 0;
-                               break;
-
-                       case SOUND_MIXER_RECMASK:
-                               val = SOUND_MASK_MIC | SOUND_MASK_LINE;
-                               break;
-
-                       case SOUND_MIXER_CAPS:
-                               val = 0;
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               val = gus_mic_vol | (gus_mic_vol << 8);
-                               break;
-
-                       case SOUND_MIXER_LINE:
-                               val = gus_line_vol | (gus_line_vol << 8);
-                               break;
-
-                       case SOUND_MIXER_PCM:
-                               val = gus_pcm_volume | (gus_pcm_volume << 8);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = gus_wave_volume | (gus_wave_volume << 8);
-                               break;
-
-                       default:
-                               return -EINVAL;
-               }
-       }
-       return __put_user(val, (int __user *)arg);
-}
-
-static struct mixer_operations gus_mixer_operations =
-{
-       .owner  = THIS_MODULE,
-       .id     = "GUS",
-       .name   = "Gravis Ultrasound",
-       .ioctl  = gus_default_mixer_ioctl
-};
-
-static int __init gus_default_mixer_init(void)
-{
-       int n;
-
-       if ((n = sound_alloc_mixerdev()) != -1)
-       {       
-               /*
-                * Don't install if there is another
-                * mixer
-                */
-               mixer_devs[n] = &gus_mixer_operations;
-       }
-       if (have_gus_max)
-       {
-               /*
-                *  Enable all mixer channels on the GF1 side. Otherwise recording will
-                *  not be possible using GUS MAX.
-                */
-               mix_image &= ~0x07;
-               mix_image |= 0x04;      /* All channels enabled */
-               outb((mix_image), u_Mixer);
-       }
-       return n;
-}
-
-void __init gus_wave_init(struct address_info *hw_config)
-{
-       unsigned long flags;
-       unsigned char val;
-       char *model_num = "2.4";
-       char tmp[64];
-       int gus_type = 0x24;    /* 2.4 */
-
-       int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
-       int sdev;
-
-       hw_config->slots[0] = -1;       /* No wave */
-       hw_config->slots[1] = -1;       /* No ad1848 */
-       hw_config->slots[4] = -1;       /* No audio */
-       hw_config->slots[5] = -1;       /* No mixer */
-
-       if (!gus_pnp_flag)
-       {
-               if (irq < 0 || irq > 15)
-               {
-                       printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq);
-                       return;
-               }
-       }
-       
-       if (dma < 0 || dma > 7 || dma == 4)
-       {
-               printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma);
-               return;
-       }
-       gus_irq = irq;
-       gus_dma = dma;
-       gus_dma2 = dma2;
-       gus_hw_config = hw_config;
-
-       if (gus_dma2 == -1)
-               gus_dma2 = dma;
-
-       /*
-        * Try to identify the GUS model.
-        *
-        *  Versions < 3.6 don't have the digital ASIC. Try to probe it first.
-        */
-
-       spin_lock_irqsave(&gus_lock,flags);
-       outb((0x20), gus_base + 0x0f);
-       val = inb(gus_base + 0x0f);
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (gus_pnp_flag || (val != 0xff && (val & 0x06)))      /* Should be 0x02?? */
-       {
-               int             ad_flags = 0;
-
-               if (gus_pnp_flag)
-                       ad_flags = 0x12345678;  /* Interwave "magic" */
-               /*
-                * It has the digital ASIC so the card is at least v3.4.
-                * Next try to detect the true model.
-                */
-
-               if (gus_pnp_flag)       /* Hack hack hack */
-                       val = 10;
-               else
-                       val = inb(u_MixSelect);
-
-               /*
-                * Value 255 means pre-3.7 which don't have mixer.
-                * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
-                * 10 and above is GUS MAX which has the CS4231 codec/mixer.
-                *
-                */
-
-               if (val == 255 || val < 5)
-               {
-                       model_num = "3.4";
-                       gus_type = 0x34;
-               }
-               else if (val < 10)
-               {
-                       model_num = "3.7";
-                       gus_type = 0x37;
-                       mixer_type = ICS2101;
-                       request_region(u_MixSelect, 1, "GUS mixer");
-               }
-               else
-               {
-                       struct resource *ports;
-                       ports = request_region(gus_base + 0x10c, 4, "ad1848");
-                       model_num = "MAX";
-                       gus_type = 0x40;
-                       mixer_type = CS4231;
-#ifdef CONFIG_SOUND_GUSMAX
-                       {
-                               unsigned char   max_config = 0x40;      /* Codec enable */
-
-                               if (gus_dma2 == -1)
-                                       gus_dma2 = gus_dma;
-
-                               if (gus_dma > 3)
-                                       max_config |= 0x10;             /* 16 bit capture DMA */
-
-                               if (gus_dma2 > 3)
-                                       max_config |= 0x20;             /* 16 bit playback DMA */
-
-                               max_config |= (gus_base >> 4) & 0x0f;   /* Extract the X from 2X0 */
-
-                               outb((max_config), gus_base + 0x106);   /* UltraMax control */
-                       }
-
-                       if (!ports)
-                               goto no_cs4231;
-
-                       if (ad1848_detect(ports, &ad_flags, hw_config->osp))
-                       {
-                               char           *name = "GUS MAX";
-                               int             old_num_mixers = num_mixers;
-
-                               if (gus_pnp_flag)
-                                       name = "GUS PnP";
-
-                               gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-                               gus_wave_volume = 90;
-                               have_gus_max = 1;
-                               if (hw_config->name)
-                                       name = hw_config->name;
-
-                               hw_config->slots[1] = ad1848_init(name, ports,
-                                                       -irq, gus_dma2, /* Playback DMA */
-                                                       gus_dma,        /* Capture DMA */
-                                                       1,              /* Share DMA channels with GF1 */
-                                                       hw_config->osp,
-                                                       THIS_MODULE);
-
-                               if (num_mixers > old_num_mixers)
-                               {
-                                       /* GUS has it's own mixer map */
-                                       AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH);
-                                       AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
-                                       AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-                               }
-                       }
-                       else {
-                               release_region(gus_base + 0x10c, 4);
-                       no_cs4231:
-                               printk(KERN_WARNING "GUS: No CS4231 ??");
-                       }
-#else
-                       printk(KERN_ERR "GUS MAX found, but not compiled in\n");
-#endif
-               }
-       }
-       else
-       {
-               /*
-                * ASIC not detected so the card must be 2.2 or 2.4.
-                * There could still be the 16-bit/mixer daughter card.
-                */
-       }
-
-       if (hw_config->name)
-               snprintf(tmp, sizeof(tmp), "%s (%dk)", hw_config->name,
-                        (int) gus_mem_size / 1024);
-       else if (gus_pnp_flag)
-               snprintf(tmp, sizeof(tmp), "Gravis UltraSound PnP (%dk)",
-                        (int) gus_mem_size / 1024);
-       else
-               snprintf(tmp, sizeof(tmp), "Gravis UltraSound %s (%dk)", model_num,
-                        (int) gus_mem_size / 1024);
-
-
-       samples = (struct patch_info *)vmalloc((MAX_SAMPLE + 1) * sizeof(*samples));
-       if (samples == NULL)
-       {
-               printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n");
-               return;
-       }
-       conf_printf(tmp, hw_config);
-       strlcpy(gus_info.name, tmp, sizeof(gus_info.name));
-
-       if ((sdev = sound_alloc_synthdev()) == -1)
-               printk(KERN_WARNING "gus_init: Too many synthesizers\n");
-       else
-       {
-               voice_alloc = &guswave_operations.alloc;
-               if (iw_mode)
-                       guswave_operations.id = "IWAVE";
-               hw_config->slots[0] = sdev;
-               synth_devs[sdev] = &guswave_operations;
-               sequencer_init();
-               gus_tmr_install(gus_base + 8);
-       }
-
-       reset_sample_memory();
-
-       gus_initialize();
-       
-       if ((gus_mem_size > 0) && !gus_no_wave_dma)
-       {
-               hw_config->slots[4] = -1;
-               if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
-                                       "Ultrasound",
-                                       &gus_audio_driver,
-                                       sizeof(struct audio_driver),
-                                       NEEDS_RESTART |
-                                       ((!iw_mode && dma2 != dma && dma2 != -1) ?
-                                               DMA_DUPLEX : 0),
-                                       AFMT_U8 | AFMT_S16_LE,
-                                       NULL, dma, dma2)) < 0)
-               {
-                       return;
-               }
-
-               hw_config->slots[4] = gus_devnum;
-               audio_devs[gus_devnum]->min_fragment = 9;       /* 512k */
-               audio_devs[gus_devnum]->max_fragment = 11;      /* 8k (must match size of bounce_buf */
-               audio_devs[gus_devnum]->mixer_dev = -1; /* Next mixer# */
-               audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
-       }
-       
-       /*
-        *  Mixer dependent initialization.
-        */
-
-       switch (mixer_type)
-       {
-               case ICS2101:
-                       gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-                       gus_wave_volume = 90;
-                       request_region(u_MixSelect, 1, "GUS mixer");
-                       hw_config->slots[5] = ics2101_mixer_init();
-                       audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];        /* Next mixer# */
-                       return;
-
-               case CS4231:
-                       /* Initialized elsewhere (ad1848.c) */
-               default:
-                       hw_config->slots[5] = gus_default_mixer_init();
-                       audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];        /* Next mixer# */
-                       return;
-       }
-}
-
-void __exit gus_wave_unload(struct address_info *hw_config)
-{
-#ifdef CONFIG_SOUND_GUSMAX
-       if (have_gus_max)
-       {
-               ad1848_unload(gus_base + 0x10c,
-                               -gus_irq,
-                               gus_dma2,       /* Playback DMA */
-                               gus_dma,        /* Capture DMA */
-                               1);     /* Share DMA channels with GF1 */
-       }
-#endif
-
-       if (mixer_type == ICS2101)
-       {
-               release_region(u_MixSelect, 1);
-       }
-       if (hw_config->slots[0] != -1)
-               sound_unload_synthdev(hw_config->slots[0]);
-       if (hw_config->slots[1] != -1)
-               sound_unload_audiodev(hw_config->slots[1]);
-       if (hw_config->slots[2] != -1)
-               sound_unload_mididev(hw_config->slots[2]);
-       if (hw_config->slots[4] != -1)
-               sound_unload_audiodev(hw_config->slots[4]);
-       if (hw_config->slots[5] != -1)
-               sound_unload_mixerdev(hw_config->slots[5]);
-       
-       vfree(samples);
-       samples=NULL;
-}
-/* called in interrupt context */
-static void do_loop_irq(int voice)
-{
-       unsigned char   tmp;
-       int             mode, parm;
-
-       spin_lock(&gus_lock);
-       gus_select_voice(voice);
-
-       tmp = gus_read8(0x00);
-       tmp &= ~0x20;           /*
-                                * Disable wave IRQ for this_one voice
-                                */
-       gus_write8(0x00, tmp);
-
-       if (tmp & 0x03)         /* Voice stopped */
-               voice_alloc->map[voice] = 0;
-
-       mode = voices[voice].loop_irq_mode;
-       voices[voice].loop_irq_mode = 0;
-       parm = voices[voice].loop_irq_parm;
-
-       switch (mode)
-       {
-               case LMODE_FINISH:      /*
-                                        * Final loop finished, shoot volume down
-                                        */
-
-                       if ((int) (gus_read16(0x09) >> 4) < 100)        /*
-                                                                        * Get current volume
-                                                                        */
-                       {
-                               gus_voice_off();
-                               gus_rampoff();
-                               gus_voice_init(voice);
-                               break;
-                       }
-                       gus_ramp_range(65, 4065);
-                       gus_ramp_rate(0, 63);           /*
-                                                        * Fastest possible rate
-                                                        */
-                       gus_rampon(0x20 | 0x40);        /*
-                                                        * Ramp down, once, irq
-                                                        */
-                       voices[voice].volume_irq_mode = VMODE_HALT;
-                       break;
-
-               case LMODE_PCM_STOP:
-                       pcm_active = 0; /* Signal to the play_next_pcm_block routine */
-               case LMODE_PCM:
-               {
-                       pcm_qlen--;
-                       pcm_head = (pcm_head + 1) % pcm_nblk;
-                       if (pcm_qlen && pcm_active)
-                       {
-                               play_next_pcm_block();
-                       }
-                       else
-                       {
-                               /* Underrun. Just stop the voice */
-                               gus_select_voice(0);    /* Left channel */
-                               gus_voice_off();
-                               gus_rampoff();
-                               gus_select_voice(1);    /* Right channel */
-                               gus_voice_off();
-                               gus_rampoff();
-                               pcm_active = 0;
-                       }
-
-                       /*
-                        * If the queue was full before this interrupt, the DMA transfer was
-                        * suspended. Let it continue now.
-                        */
-                       
-                       if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-                               DMAbuf_outputintr(gus_devnum, 0);
-               }
-               break;
-
-               default:
-                       break;
-       }
-       spin_unlock(&gus_lock);
-}
-
-static void do_volume_irq(int voice)
-{
-       unsigned char tmp;
-       int mode, parm;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       gus_select_voice(voice);
-       tmp = gus_read8(0x0d);
-       tmp &= ~0x20;           /*
-                                * Disable volume ramp IRQ
-                                */
-       gus_write8(0x0d, tmp);
-
-       mode = voices[voice].volume_irq_mode;
-       voices[voice].volume_irq_mode = 0;
-       parm = voices[voice].volume_irq_parm;
-
-       switch (mode)
-       {
-               case VMODE_HALT:        /* Decay phase finished */
-                       if (iw_mode)
-                               gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       gus_voice_init(voice);
-                       break;
-
-               case VMODE_ENVELOPE:
-                       gus_rampoff();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       step_envelope(voice);
-                       break;
-
-               case VMODE_START_NOTE:
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       guswave_start_note2(voices[voice].dev_pending, voice,
-                                     voices[voice].note_pending, voices[voice].volume_pending);
-                       if (voices[voice].kill_pending)
-                               guswave_kill_note(voices[voice].dev_pending, voice,
-                                         voices[voice].note_pending, 0);
-
-                       if (voices[voice].sample_pending >= 0)
-                       {
-                               guswave_set_instr(voices[voice].dev_pending, voice,
-                                       voices[voice].sample_pending);
-                               voices[voice].sample_pending = -1;
-                       }
-                       break;
-
-               default:
-                       spin_unlock_irqrestore(&gus_lock,flags);
-       }
-}
-/* called in irq context */
-void gus_voice_irq(void)
-{
-       unsigned long wave_ignore = 0, volume_ignore = 0;
-       unsigned long voice_bit;
-
-       unsigned char src, voice;
-
-       while (1)
-       {
-               src = gus_read8(0x0f);  /*
-                                        * Get source info
-                                        */
-               voice = src & 0x1f;
-               src &= 0xc0;
-
-               if (src == (0x80 | 0x40))
-                       return; /*
-                                * No interrupt
-                                */
-
-               voice_bit = 1 << voice;
-
-               if (!(src & 0x80))      /*
-                                        * Wave IRQ pending
-                                        */
-                       if (!(wave_ignore & voice_bit) && (int) voice < nr_voices)      /*
-                                                                                        * Not done
-                                                                                        * yet
-                                                                                        */
-                       {
-                               wave_ignore |= voice_bit;
-                               do_loop_irq(voice);
-                       }
-               if (!(src & 0x40))      /*
-                                        * Volume IRQ pending
-                                        */
-                       if (!(volume_ignore & voice_bit) && (int) voice < nr_voices)    /*
-                                                                                          * Not done
-                                                                                          * yet
-                                                                                        */
-                       {
-                               volume_ignore |= voice_bit;
-                               do_volume_irq(voice);
-                       }
-       }
-}
-
-void guswave_dma_irq(void)
-{
-       unsigned char   status;
-
-       status = gus_look8(0x41);       /* Get DMA IRQ Status */
-       if (status & 0x40)      /* DMA interrupt pending */
-               switch (active_device)
-               {
-                       case GUS_DEV_WAVE:
-                               wake_up(&dram_sleeper);
-                               break;
-
-                       case GUS_DEV_PCM_CONTINUE:      /* Left channel data transferred */
-                               gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                               gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
-                                               pcm_current_count,
-                                               pcm_current_intrflag, 1);
-                               break;
-
-                       case GUS_DEV_PCM_DONE:  /* Right or mono channel data transferred */
-                               gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                               if (pcm_qlen < pcm_nblk)
-                               {
-                                       dma_active = 0;
-                                       if (gus_busy)
-                                       {
-                                               if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-                                                       DMAbuf_outputintr(gus_devnum, 0);
-                                       }
-                               }
-                               break;
-
-                       default:
-                               break;
-       }
-       status = gus_look8(0x49);       /*
-                                        * Get Sampling IRQ Status
-                                        */
-       if (status & 0x40)      /*
-                                * Sampling Irq pending
-                                */
-       {
-               DMAbuf_inputintr(gus_devnum);
-       }
-}
-
-/*
- * Timer stuff
- */
-
-static volatile int select_addr, data_addr;
-static volatile int curr_timer;
-
-void gus_timer_command(unsigned int addr, unsigned int val)
-{
-       int i;
-
-       outb(((unsigned char) (addr & 0xff)), select_addr);
-
-       for (i = 0; i < 2; i++)
-               inb(select_addr);
-
-       outb(((unsigned char) (val & 0xff)), data_addr);
-
-       for (i = 0; i < 2; i++)
-               inb(select_addr);
-}
-
-static void arm_timer(int timer, unsigned int interval)
-{
-       curr_timer = timer;
-
-       if (timer == 1)
-       {
-               gus_write8(0x46, 256 - interval);       /* Set counter for timer 1 */
-               gus_write8(0x45, 0x04);                 /* Enable timer 1 IRQ */
-               gus_timer_command(0x04, 0x01);          /* Start timer 1 */
-       }
-       else
-       {
-               gus_write8(0x47, 256 - interval);       /* Set counter for timer 2 */
-               gus_write8(0x45, 0x08);                 /* Enable timer 2 IRQ */
-               gus_timer_command(0x04, 0x02);          /* Start timer 2 */
-       }
-
-       gus_timer_enabled = 1;
-}
-
-static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick)
-{
-       int timer_no, resolution;
-       int divisor;
-
-       if (usecs_per_tick > (256 * 80))
-       {
-               timer_no = 2;
-               resolution = 320;       /* usec */
-       }
-       else
-       {
-               timer_no = 1;
-               resolution = 80;        /* usec */
-       }
-       divisor = (usecs_per_tick + (resolution / 2)) / resolution;
-       arm_timer(timer_no, divisor);
-
-       return divisor * resolution;
-}
-
-static void gus_tmr_disable(int dev)
-{
-       gus_write8(0x45, 0);    /* Disable both timers */
-       gus_timer_enabled = 0;
-}
-
-static void gus_tmr_restart(int dev)
-{
-       if (curr_timer == 1)
-               gus_write8(0x45, 0x04);         /* Start timer 1 again */
-       else
-               gus_write8(0x45, 0x08);         /* Start timer 2 again */
-       gus_timer_enabled = 1;
-}
-
-static struct sound_lowlev_timer gus_tmr =
-{
-       0,
-       1,
-       gus_tmr_start,
-       gus_tmr_disable,
-       gus_tmr_restart
-};
-
-static void gus_tmr_install(int io_base)
-{
-       struct sound_lowlev_timer *tmr;
-
-       select_addr = io_base;
-       data_addr = io_base + 1;
-
-       tmr = &gus_tmr;
-
-#ifdef THIS_GETS_FIXED
-       sound_timer_init(&gus_tmr, "GUS");
-#endif
-}
diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c
deleted file mode 100644 (file)
index 591683c..0000000
+++ /dev/null
@@ -1,1330 +0,0 @@
-/*
-       drivers/sound/harmony.c 
-
-       This is a sound driver for ASP's and Lasi's Harmony sound chip
-       and is unlikely to be used for anything other than on a HP PA-RISC.
-
-       Harmony is found in HP 712s, 715/new and many other GSC based machines.
-       On older 715 machines you'll find the technically identical chip 
-       called 'Vivace'. Both Harmony and Vicace are supported by this driver.
-
-       Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@onefishtwo.ca>
-       Copyright 2000-2003 (c) Helge Deller <deller@gmx.de>
-       Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
-       Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
-       Copyright 2004 (c) Stuart Brady <sdbrady@ntlworld.com>
-
-                               
-TODO:
-       - fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to
-               return the real values
-       - add private ioctl for selecting line- or microphone input
-               (only one of them is available at the same time)
-       - add module parameters
-       - implement mmap functionality
-       - implement gain meter ?
-       - ...
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-
-#include <asm/parisc-device.h>
-#include <asm/io.h>
-
-#include "sound_config.h"
-
-
-#define PFX "harmony: "
-#define HARMONY_VERSION "V0.9a"
-
-#undef DEBUG
-#ifdef DEBUG
-# define DPRINTK printk 
-#else
-# define DPRINTK(x,...)
-#endif
-
-
-#define MAX_BUFS 10            /* maximum number of rotating buffers */
-#define HARMONY_BUF_SIZE 4096  /* needs to be a multiple of PAGE_SIZE (4096)! */
-
-#define CNTL_C         0x80000000
-#define        CNTL_ST         0x00000020
-#define CNTL_44100     0x00000015      /* HARMONY_SR_44KHZ */
-#define CNTL_8000      0x00000008      /* HARMONY_SR_8KHZ */
-
-#define GAINCTL_HE     0x08000000
-#define GAINCTL_LE     0x04000000
-#define GAINCTL_SE     0x02000000
-
-#define DSTATUS_PN     0x00000200
-#define DSTATUS_RN     0x00000002
-
-#define DSTATUS_IE     0x80000000
-
-#define HARMONY_DF_16BIT_LINEAR        0
-#define HARMONY_DF_8BIT_ULAW   1
-#define HARMONY_DF_8BIT_ALAW   2
-
-#define HARMONY_SS_MONO                0
-#define HARMONY_SS_STEREO      1
-
-#define HARMONY_SR_8KHZ                0x08
-#define HARMONY_SR_16KHZ       0x09
-#define HARMONY_SR_27KHZ       0x0A
-#define HARMONY_SR_32KHZ       0x0B
-#define HARMONY_SR_48KHZ       0x0E
-#define HARMONY_SR_9KHZ                0x0F
-#define HARMONY_SR_5KHZ                0x10
-#define HARMONY_SR_11KHZ       0x11
-#define HARMONY_SR_18KHZ       0x12
-#define HARMONY_SR_22KHZ       0x13
-#define HARMONY_SR_37KHZ       0x14
-#define HARMONY_SR_44KHZ       0x15
-#define HARMONY_SR_33KHZ       0x16
-#define HARMONY_SR_6KHZ                0x17
-
-/*
- * Some magics numbers used to auto-detect file formats
- */
-
-#define HARMONY_MAGIC_8B_ULAW  1
-#define HARMONY_MAGIC_8B_ALAW  27
-#define HARMONY_MAGIC_16B_LINEAR 3
-#define HARMONY_MAGIC_MONO     1
-#define HARMONY_MAGIC_STEREO   2
-
-/*
- * Channels Positions in mixer register
- */
-
-#define GAIN_HE_SHIFT   27
-#define GAIN_HE_MASK    ( 1 << GAIN_HE_SHIFT) 
-#define GAIN_LE_SHIFT   26
-#define GAIN_LE_MASK    ( 1 << GAIN_LE_SHIFT) 
-#define GAIN_SE_SHIFT   25
-#define GAIN_SE_MASK    ( 1 << GAIN_SE_SHIFT) 
-#define GAIN_IS_SHIFT   24
-#define GAIN_IS_MASK    ( 1 << GAIN_IS_SHIFT) 
-#define GAIN_MA_SHIFT   20
-#define GAIN_MA_MASK    ( 0x0f << GAIN_MA_SHIFT) 
-#define GAIN_LI_SHIFT   16
-#define GAIN_LI_MASK    ( 0x0f << GAIN_LI_SHIFT) 
-#define GAIN_RI_SHIFT   12
-#define GAIN_RI_MASK    ( 0x0f << GAIN_RI_SHIFT) 
-#define GAIN_LO_SHIFT   6
-#define GAIN_LO_MASK    ( 0x3f << GAIN_LO_SHIFT) 
-#define GAIN_RO_SHIFT   0
-#define GAIN_RO_MASK    ( 0x3f << GAIN_RO_SHIFT) 
-
-
-#define MAX_OUTPUT_LEVEL  (GAIN_RO_MASK >> GAIN_RO_SHIFT)
-#define MAX_INPUT_LEVEL   (GAIN_RI_MASK >> GAIN_RI_SHIFT)
-#define MAX_MONITOR_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT)
-
-#define MIXER_INTERNAL   SOUND_MIXER_LINE1
-#define MIXER_LINEOUT    SOUND_MIXER_LINE2
-#define MIXER_HEADPHONES SOUND_MIXER_LINE3
-
-#define MASK_INTERNAL   SOUND_MASK_LINE1
-#define MASK_LINEOUT    SOUND_MASK_LINE2
-#define MASK_HEADPHONES SOUND_MASK_LINE3
-
-/*
- * Channels Mask in mixer register
- */
-
-#define GAIN_TOTAL_SILENCE 0x00F00FFF
-#define GAIN_DEFAULT       0x0FF00000
-
-
-struct harmony_hpa {
-       u8      unused000;
-       u8      id;
-       u8      teleshare_id;
-       u8      unused003;
-       u32     reset;
-       u32     cntl;
-       u32     gainctl;
-       u32     pnxtadd;
-       u32     pcuradd;
-       u32     rnxtadd;
-       u32     rcuradd;
-       u32     dstatus;
-       u32     ov;
-       u32     pio;
-       u32     unused02c;
-       u32     unused030[3];
-       u32     diag;
-};
-
-struct harmony_dev {
-       struct harmony_hpa *hpa;
-       struct parisc_device *dev;
-       u32 current_gain;
-       u32 dac_rate;           /* 8000 ... 48000 (Hz) */
-       u8 data_format;         /* HARMONY_DF_xx_BIT_xxx */
-       u8 sample_rate;         /* HARMONY_SR_xx_KHZ */
-       u8 stereo_select;       /* HARMONY_SS_MONO or HARMONY_SS_STEREO */
-       int format_initialized  :1;
-       int suspended_playing   :1;
-       int suspended_recording :1;
-       
-       int blocked_playing     :1;
-       int blocked_recording   :1;
-       int audio_open          :1;
-       int mixer_open          :1;
-       
-       wait_queue_head_t wq_play, wq_record;
-       int first_filled_play;  /* first buffer containing data (next to play) */
-       int nb_filled_play; 
-       int play_offset;
-       int first_filled_record;
-       int nb_filled_record;
-               
-       int dsp_unit, mixer_unit;
-};
-
-
-static struct harmony_dev harmony;
-
-
-/*
- * Dynamic sound buffer allocation and DMA memory
- */
-
-struct harmony_buffer {
-       unsigned char *addr;
-       dma_addr_t dma_handle;
-       int dma_coherent;       /* Zero if dma_alloc_coherent() fails */
-       unsigned int len;
-};
-
-/*
- * Harmony memory buffers
- */
-
-static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
-
-
-#define CHECK_WBACK_INV_OFFSET(b,offset,len) \
-        do { if (!b.dma_coherent) \
-               dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
-       } while (0) 
-
-       
-static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
-               unsigned int buffer_count)
-{
-       b->len = buffer_count * HARMONY_BUF_SIZE;
-       b->addr = dma_alloc_coherent(&harmony.dev->dev, 
-                         b->len, &b->dma_handle, GFP_KERNEL|GFP_DMA);
-       if (b->addr && b->dma_handle) {
-               b->dma_coherent = 1;
-               DPRINTK(KERN_INFO PFX "coherent memory: 0x%lx, played_buf: 0x%lx\n",
-                               (unsigned long)b->dma_handle, (unsigned long)b->addr);
-       } else {
-               b->dma_coherent = 0;
-               /* kmalloc()ed memory will HPMC on ccio machines ! */
-               b->addr = kmalloc(b->len, GFP_KERNEL);
-               if (!b->addr) {
-                       printk(KERN_ERR PFX "couldn't allocate memory\n");
-                       return -EBUSY;
-               }
-               b->dma_handle = __pa(b->addr);
-       }
-       return 0;
-}
-
-static void __exit harmony_free_buffer(struct harmony_buffer *b)
-{
-       if (!b->addr)
-               return;
-
-       if (b->dma_coherent)
-               dma_free_coherent(&harmony.dev->dev,
-                               b->len, b->addr, b->dma_handle);
-       else
-               kfree(b->addr);
-
-       memset(b, 0, sizeof(*b));
-}
-
-
-
-/*
- * Low-Level sound-chip programming
- */
-
-static void __inline__ harmony_wait_CNTL(void)
-{
-       /* Wait until we're out of control mode */
-       while (gsc_readl(&harmony.hpa->cntl) & CNTL_C)
-               /* wait */ ;
-}
-
-
-static void harmony_update_control(void) 
-{
-       u32 default_cntl;
-       
-       /* Set CNTL */
-       default_cntl = (CNTL_C |                /* The C bit */
-               (harmony.data_format << 6) |    /* Set the data format */
-               (harmony.stereo_select << 5) |  /* Stereo select */
-               (harmony.sample_rate));         /* Set sample rate */
-       harmony.format_initialized = 1;
-       
-       /* initialize CNTL */
-       gsc_writel(default_cntl, &harmony.hpa->cntl);
-}
-
-static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) 
-{
-       harmony.sample_rate = sample_rate;
-       harmony.data_format = data_format;
-       harmony.stereo_select = stereo_select;
-       harmony_update_control();
-}
-
-static void harmony_set_rate(u8 data_rate) 
-{
-       harmony.sample_rate = data_rate;
-       harmony_update_control();
-}
-
-static int harmony_detect_rate(int *freq)
-{
-       int newrate;
-       switch (*freq) {
-       case 8000:      newrate = HARMONY_SR_8KHZ;      break;
-       case 16000:     newrate = HARMONY_SR_16KHZ;     break; 
-       case 27428:     newrate = HARMONY_SR_27KHZ;     break; 
-       case 32000:     newrate = HARMONY_SR_32KHZ;     break; 
-       case 48000:     newrate = HARMONY_SR_48KHZ;     break; 
-       case 9600:      newrate = HARMONY_SR_9KHZ;      break; 
-       case 5512:      newrate = HARMONY_SR_5KHZ;      break; 
-       case 11025:     newrate = HARMONY_SR_11KHZ;     break; 
-       case 18900:     newrate = HARMONY_SR_18KHZ;     break; 
-       case 22050:     newrate = HARMONY_SR_22KHZ;     break; 
-       case 37800:     newrate = HARMONY_SR_37KHZ;     break; 
-       case 44100:     newrate = HARMONY_SR_44KHZ;     break; 
-       case 33075:     newrate = HARMONY_SR_33KHZ;     break; 
-       case 6615:      newrate = HARMONY_SR_6KHZ;      break; 
-       default:        newrate = HARMONY_SR_8KHZ; 
-                       *freq = 8000;                   break;
-       }
-       return newrate;
-}
-
-static void harmony_set_format(u8 data_format) 
-{
-       harmony.data_format = data_format;
-       harmony_update_control();
-}
-
-static void harmony_set_stereo(u8 stereo_select) 
-{
-       harmony.stereo_select = stereo_select;
-       harmony_update_control();
-}
-
-static void harmony_disable_interrupts(void) 
-{
-       harmony_wait_CNTL();
-       gsc_writel(0, &harmony.hpa->dstatus); 
-}
-
-static void harmony_enable_interrupts(void) 
-{
-       harmony_wait_CNTL();
-       gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); 
-}
-
-/*
- * harmony_silence()
- *
- * This subroutine fills in a buffer starting at location start and
- * silences for length bytes.  This references the current
- * configuration of the audio format.
- *
- */
-
-static void harmony_silence(struct harmony_buffer *buffer, int start, int length) 
-{
-       u8 silence_char;
-
-       /* Despite what you hear, silence is different in
-          different audio formats.  */
-       switch (harmony.data_format) {
-               case HARMONY_DF_8BIT_ULAW:      silence_char = 0x55; break;
-               case HARMONY_DF_8BIT_ALAW:      silence_char = 0xff; break;
-               case HARMONY_DF_16BIT_LINEAR:   /* fall through */
-               default:                        silence_char = 0;
-       }
-
-       memset(buffer->addr+start, silence_char, length);
-}
-
-
-static int harmony_audio_open(struct inode *inode, struct file *file)
-{
-       if (harmony.audio_open) 
-               return -EBUSY;
-       
-       harmony.audio_open = 1;
-       harmony.suspended_playing = harmony.suspended_recording = 1;
-       harmony.blocked_playing   = harmony.blocked_recording   = 0;
-       harmony.first_filled_play = harmony.first_filled_record = 0;
-       harmony.nb_filled_play    = harmony.nb_filled_record    = 0;
-       harmony.play_offset = 0;
-       init_waitqueue_head(&harmony.wq_play);
-       init_waitqueue_head(&harmony.wq_record);
-       
-       /* Start off in a balanced mode. */
-       harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-       harmony_update_control();
-       harmony.format_initialized = 0;
-
-       /* Clear out all the buffers and flush to cache */
-       harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-       CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-       
-       return 0;
-}
-
-/*
- * Release (close) the audio device.
- */
-
-static int harmony_audio_release(struct inode *inode, struct file *file)
-{
-       if (!harmony.audio_open) 
-               return -EBUSY;
-       
-       harmony.audio_open = 0;
-
-       return 0;
-}
-
-/*
- * Read recorded data off the audio device.
- */
-
-static ssize_t harmony_audio_read(struct file *file,
-                                char *buffer,
-                                size_t size_count,
-                                loff_t *ppos)
-{
-       int total_count = (int) size_count;
-       int count = 0;
-       int buf_to_read;
-
-       while (count<total_count) {
-               /* Wait until we're out of control mode */
-               harmony_wait_CNTL();
-               
-               /* Figure out which buffer to fill in */
-               if (harmony.nb_filled_record <= 2) {
-                       harmony.blocked_recording = 1;
-                       if (harmony.suspended_recording) {
-                               harmony.suspended_recording = 0;
-                               harmony_enable_interrupts();
-                       }
-                                                       
-                       interruptible_sleep_on(&harmony.wq_record);
-                       harmony.blocked_recording = 0;
-               }
-               
-               if (harmony.nb_filled_record < 2)
-                       return -EBUSY;
-               
-               buf_to_read = harmony.first_filled_record;
-
-               /* Copy the page to an aligned buffer */
-               if (copy_to_user(buffer+count, recorded_buf.addr +
-                                (HARMONY_BUF_SIZE*buf_to_read),
-                                HARMONY_BUF_SIZE)) {
-                       count = -EFAULT;
-                       break;
-               }
-               
-               harmony.nb_filled_record--;
-               harmony.first_filled_record++;
-               harmony.first_filled_record %= MAX_BUFS;
-                               
-               count += HARMONY_BUF_SIZE;
-       }
-       return count;
-}
-
-
-
-
-/*
- * Here is the place where we try to recognize file format.
- * Sun/NeXT .au files begin with the string .snd
- * At offset 12 is specified the encoding.
- * At offset 16 is specified speed rate
- * At Offset 20 is specified the numbers of voices
- */
-
-#define four_bytes_to_u32(start) (file_header[start] << 24)|\
-                                  (file_header[start+1] << 16)|\
-                                  (file_header[start+2] << 8)|\
-                                  (file_header[start+3]);
-
-#define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\
-                                                    
-
-static int harmony_format_auto_detect(const char *buffer, int block_size)
-{
-       u8 file_header[24];
-       u32 start_string;
-       int ret = 0;
-       
-       if (block_size>24) {
-               if (copy_from_user(file_header, buffer, sizeof(file_header)))
-                       ret = -EFAULT;
-                       
-               start_string = four_bytes_to_u32(0);
-               
-               if ((file_header[4]==0) && (start_string==0x2E736E64)) {
-                       u32 format;
-                       u32 nb_voices;
-                       u32 speed;
-                       
-                       format = four_bytes_to_u32(12);
-                       nb_voices = four_bytes_to_u32(20);
-                       speed = four_bytes_to_u32(16);
-                       
-                       switch (format) {
-                       case HARMONY_MAGIC_8B_ULAW:
-                               harmony.data_format = HARMONY_DF_8BIT_ULAW;
-                               break;
-                       case HARMONY_MAGIC_8B_ALAW:
-                               harmony.data_format = HARMONY_DF_8BIT_ALAW;
-                               break;
-                       case HARMONY_MAGIC_16B_LINEAR:
-                               harmony.data_format = HARMONY_DF_16BIT_LINEAR;
-                               break;
-                       default:
-                               harmony_set_control(HARMONY_DF_16BIT_LINEAR,
-                                               HARMONY_SR_44KHZ, HARMONY_SS_STEREO);
-                               goto out;
-                       }
-                       switch (nb_voices) {
-                       case HARMONY_MAGIC_MONO:
-                               harmony.stereo_select = HARMONY_SS_MONO;
-                               break;
-                       case HARMONY_MAGIC_STEREO:
-                               harmony.stereo_select = HARMONY_SS_STEREO;
-                               break;
-                       default:
-                               harmony.stereo_select = HARMONY_SS_MONO;
-                               break;
-                       }
-                       harmony_set_rate(harmony_detect_rate(&speed));
-                       harmony.dac_rate = speed;
-                       goto out;
-               }
-       }
-       harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-out:
-       return ret;
-}
-#undef four_bytes_to_u32
-
-
-static ssize_t harmony_audio_write(struct file *file,
-                                 const char *buffer,
-                                 size_t size_count,
-                                 loff_t *ppos)
-{
-       int total_count = (int) size_count;
-       int count = 0;
-       int frame_size;
-       int buf_to_fill;
-       int fresh_buffer;
-
-       if (!harmony.format_initialized) {
-               if (harmony_format_auto_detect(buffer, total_count))
-                       return -EFAULT;
-       }
-       
-       while (count<total_count) {
-               /* Wait until we're out of control mode */
-               harmony_wait_CNTL();
-
-               /* Figure out which buffer to fill in */
-               if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) {
-                       harmony.blocked_playing = 1;
-                       interruptible_sleep_on(&harmony.wq_play);
-                       harmony.blocked_playing = 0;
-               }
-               if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset)
-                       return -EBUSY;
-               
-               
-               buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); 
-               if (harmony.play_offset) {
-                       buf_to_fill--;
-                       buf_to_fill += MAX_BUFS;
-               }
-               buf_to_fill %= MAX_BUFS;
-               
-               fresh_buffer = (harmony.play_offset == 0);
-               
-               /* Figure out the size of the frame */
-               if ((total_count-count) >= HARMONY_BUF_SIZE - harmony.play_offset) {
-                       frame_size = HARMONY_BUF_SIZE - harmony.play_offset;
-               } else {
-                       frame_size = total_count - count;
-                       /* Clear out the buffer, since there we'll only be 
-                          overlaying part of the old buffer with the new one */
-                       harmony_silence(&played_buf, 
-                               HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset,
-                               HARMONY_BUF_SIZE-frame_size-harmony.play_offset);
-               }
-
-               /* Copy the page to an aligned buffer */
-               if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, 
-                                  buffer+count, frame_size))
-                       return -EFAULT;
-               CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), 
-                               frame_size);
-       
-               if (fresh_buffer)
-                       harmony.nb_filled_play++;
-               
-               count += frame_size;
-               harmony.play_offset += frame_size;
-               harmony.play_offset %= HARMONY_BUF_SIZE;
-               if (harmony.suspended_playing && (harmony.nb_filled_play>=4))
-                       harmony_enable_interrupts();
-       }
-       
-       return count;
-}
-
-static unsigned int harmony_audio_poll(struct file *file,
-                                     struct poll_table_struct *wait)
-{
-       unsigned int mask = 0;
-       
-       if (file->f_mode & FMODE_READ) {
-               if (!harmony.suspended_recording)
-                       poll_wait(file, &harmony.wq_record, wait);
-               if (harmony.nb_filled_record)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-
-       if (file->f_mode & FMODE_WRITE) {
-               if (!harmony.suspended_playing)
-                       poll_wait(file, &harmony.wq_play, wait);
-               if (harmony.nb_filled_play)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-
-       return mask;
-}
-
-static int harmony_audio_ioctl(struct inode *inode,
-                                struct file *file,
-                               unsigned int cmd,
-                                unsigned long arg)
-{
-       int ival, new_format;
-       int frag_size, frag_buf;
-       struct audio_buf_info info;
-       
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *) arg);
-
-       case SNDCTL_DSP_GETCAPS:
-               ival = DSP_CAP_DUPLEX;
-               return put_user(ival, (int *) arg);
-
-       case SNDCTL_DSP_GETFMTS:
-               ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); 
-               return put_user(ival, (int *) arg);
-       
-       case SNDCTL_DSP_SETFMT:
-               if (get_user(ival, (int *) arg)) 
-                       return -EFAULT;
-               if (ival != AFMT_QUERY) {
-                       switch (ival) {
-                       case AFMT_MU_LAW:       new_format = HARMONY_DF_8BIT_ULAW; break;
-                       case AFMT_A_LAW:        new_format = HARMONY_DF_8BIT_ALAW; break;
-                       case AFMT_S16_BE:       new_format = HARMONY_DF_16BIT_LINEAR; break;
-                       default: {
-                               DPRINTK(KERN_WARNING PFX 
-                                       "unsupported sound format 0x%04x requested.\n",
-                                       ival);
-                               ival = AFMT_S16_BE;
-                               return put_user(ival, (int *) arg);
-                       }
-                       }
-                       harmony_set_format(new_format);
-                       return 0;
-               } else {
-                       switch (harmony.data_format) {
-                       case HARMONY_DF_8BIT_ULAW:      ival = AFMT_MU_LAW; break;
-                       case HARMONY_DF_8BIT_ALAW:      ival = AFMT_A_LAW;  break;
-                       case HARMONY_DF_16BIT_LINEAR:   ival = AFMT_U16_BE; break;
-                       default: ival = 0;
-                       }
-                       return put_user(ival, (int *) arg);
-               }
-
-       case SOUND_PCM_READ_RATE:
-               ival = harmony.dac_rate;
-               return put_user(ival, (int *) arg);
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               harmony_set_rate(harmony_detect_rate(&ival));
-               harmony.dac_rate = ival;
-               return put_user(ival, (int*) arg);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               if (ival != 0 && ival != 1)
-                       return -EINVAL;
-               harmony_set_stereo(ival);
-               return 0;
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               if (ival != 1 && ival != 2) {
-                       ival = harmony.stereo_select == HARMONY_SS_MONO ? 1 : 2;
-                       return put_user(ival, (int *) arg);
-               }
-               harmony_set_stereo(ival-1);
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               ival = HARMONY_BUF_SIZE;
-               return put_user(ival, (int *) arg);
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_RESET:
-               if (!harmony.suspended_recording) {
-                       /* TODO: stop_recording() */
-               }
-               return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(ival, (int *)arg))
-                       return -EFAULT;
-               frag_size = ival & 0xffff;
-               frag_buf = (ival>>16) & 0xffff;
-               /* TODO: We use hardcoded fragment sizes and numbers for now */
-               frag_size = 12;  /* 4096 == 2^12 */
-               frag_buf  = MAX_BUFS;
-               ival = (frag_buf << 16) + frag_size;
-               return put_user(ival, (int *) arg);
-               
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               info.fragstotal = MAX_BUFS;
-                info.fragments = MAX_BUFS - harmony.nb_filled_play;
-               info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-               return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               info.fragstotal = MAX_BUFS;
-                info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record;
-               info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-               return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-       
-       case SNDCTL_DSP_SYNC:
-               return 0;
-       }
-       
-       return -EINVAL;
-}
-
-
-/*
- * harmony_interrupt()
- *
- * harmony interruption service routine
- * 
- */
-
-static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
-{
-       u32 dstatus;
-       struct harmony_hpa *hpa;
-
-       /* Setup the hpa */
-       hpa = ((struct harmony_dev *)dev)->hpa;
-       harmony_wait_CNTL();
-
-       /* Read dstatus and pcuradd (the current address) */
-       dstatus = gsc_readl(&hpa->dstatus);
-       
-       /* Turn off interrupts */
-       harmony_disable_interrupts();
-       
-       /* Check if this is a request to get the next play buffer */
-       if (dstatus & DSTATUS_PN) {
-               if (!harmony.nb_filled_play) {
-                       harmony.suspended_playing = 1;
-                       gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd);
-                                               
-                       if (!harmony.suspended_recording)
-                               harmony_enable_interrupts();
-               } else {
-                       harmony.suspended_playing = 0;
-                       gsc_writel((unsigned long)played_buf.dma_handle + 
-                                       (HARMONY_BUF_SIZE*harmony.first_filled_play),
-                                       &hpa->pnxtadd);
-                       harmony.first_filled_play++;
-                       harmony.first_filled_play %= MAX_BUFS;
-                       harmony.nb_filled_play--;
-                       
-                       harmony_enable_interrupts();
-               }
-               
-               if (harmony.blocked_playing)
-                       wake_up_interruptible(&harmony.wq_play);
-       }
-       
-       /* Check if we're being asked to fill in a recording buffer */
-       if (dstatus & DSTATUS_RN) {
-               if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording)
-               {
-                       harmony.nb_filled_record = 0;
-                       harmony.first_filled_record = 0;
-                       harmony.suspended_recording = 1;
-                       gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd);
-                       if (!harmony.suspended_playing)
-                               harmony_enable_interrupts();
-               } else {
-                       int buf_to_fill;
-                       buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS;
-                       CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE);
-                       gsc_writel((unsigned long)recorded_buf.dma_handle +
-                                       HARMONY_BUF_SIZE*buf_to_fill,
-                                       &hpa->rnxtadd);
-                       harmony.nb_filled_record++;
-                       harmony_enable_interrupts();
-               }
-
-               if (harmony.blocked_recording && harmony.nb_filled_record>3)
-                       wake_up_interruptible(&harmony.wq_record);
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * Sound playing functions
- */
-
-static struct file_operations harmony_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = harmony_audio_read,
-       .write          = harmony_audio_write,
-       .poll           = harmony_audio_poll,
-       .ioctl          = harmony_audio_ioctl,
-       .open           = harmony_audio_open,
-       .release        = harmony_audio_release,
-};
-
-static int harmony_audio_init(void)
-{
-       /* Request that IRQ */
-       if (request_irq(harmony.dev->irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
-               printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.dev->irq);
-               return -EFAULT;
-       }
-
-       harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
-       if (harmony.dsp_unit < 0) {
-               printk(KERN_ERR PFX "Error registering dsp\n");
-               free_irq(harmony.dev->irq, &harmony);
-               return -EFAULT;
-       }
-       
-       /* Clear the buffers so you don't end up with crap in the buffers. */ 
-       harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-       /* Make sure this makes it to cache */
-       CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-       /* Clear out the silent buffer and flush to cache */
-       harmony_silence(&silent, 0, HARMONY_BUF_SIZE);
-       CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE);
-       
-       harmony.audio_open = 0;
-       
-       return 0;
-}
-
-
-/*
- * mixer functions 
- */
-
-static void harmony_mixer_set_gain(void)
-{
-       harmony_wait_CNTL();
-       gsc_writel(harmony.current_gain, &harmony.hpa->gainctl);
-}
-
-/* 
- *  Read gain of selected channel.
- *  The OSS rate is from 0 (silent) to 100 -> need some conversions
- *
- *  The harmony gain are attenuation for output and monitor gain.
- *                   is amplifaction for input gain
- */
-#define to_harmony_level(level,max) ((level)*max/100)
-#define to_oss_level(level,max) ((level)*100/max)
-
-static int harmony_mixer_get_level(int channel)
-{
-       int left_level;
-       int right_level;
-
-       switch (channel) {
-               case SOUND_MIXER_VOLUME:
-                       left_level  = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT;
-                       right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT;
-                       left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-                       right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-                       return (right_level << 8)+left_level;
-                       
-               case SOUND_MIXER_IGAIN:
-                       left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT;
-                       right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT;
-                       left_level = to_oss_level(left_level, MAX_INPUT_LEVEL);
-                       right_level= to_oss_level(right_level, MAX_INPUT_LEVEL);
-                       return (right_level << 8)+left_level;
-                       
-               case SOUND_MIXER_MONITOR:
-                       left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT;
-                       left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-                       return (left_level << 8)+left_level;
-       }
-       return -EINVAL;
-}
-
-
-
-/*
- * Some conversions for the same reasons.
- * We give back the new real value(s) due to
- * the rescale.
- */
-
-static int harmony_mixer_set_level(int channel, int value)
-{
-       int left_level;
-       int right_level;
-       int new_left_level;
-       int new_right_level;
-
-       right_level = (value & 0x0000ff00) >> 8;
-       left_level = value & 0x000000ff;
-       if (right_level > 100) right_level = 100;
-       if (left_level > 100) left_level = 100;
-  
-       switch (channel) {
-               case SOUND_MIXER_VOLUME:
-                       right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL);
-                       left_level  = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL);
-                       new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-                       new_left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) 
-                                       | (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_right_level << 8) + new_left_level;
-                       
-               case SOUND_MIXER_IGAIN:
-                       right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL);
-                       left_level  = to_harmony_level(left_level, MAX_INPUT_LEVEL);
-                       new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL);
-                       new_left_level  = to_oss_level(left_level, MAX_INPUT_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK))
-                                       | (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_right_level << 8) + new_left_level;
-       
-               case SOUND_MIXER_MONITOR:
-                       left_level = to_harmony_level(100-left_level, MAX_MONITOR_LEVEL);
-                       new_left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK) | (left_level << GAIN_MA_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_left_level << 8) + new_left_level;
-       }
-
-       return -EINVAL;
-}
-
-#undef to_harmony_level
-#undef to_oss_level
-
-/* 
- * Return the selected input device (mic or line)
- */
-
-static int harmony_mixer_get_recmask(void) 
-{
-       int current_input_line;
-       
-       current_input_line = (harmony.current_gain & GAIN_IS_MASK) 
-                                   >> GAIN_IS_SHIFT;
-       if (current_input_line) 
-               return SOUND_MASK_MIC;
-
-       return SOUND_MASK_LINE;
-}
-
-/*
- * Set the input (only one at time, arbitrary priority to line in)
- */
-
-static int harmony_mixer_set_recmask(int recmask)
-{
-       int new_input_line;
-       int new_input_mask;
-       int current_input_line;
-       
-       current_input_line = (harmony.current_gain & GAIN_IS_MASK)
-                                   >> GAIN_IS_SHIFT;
-       if ((current_input_line && ((recmask & SOUND_MASK_LINE) || !(recmask & SOUND_MASK_MIC))) ||
-               (!current_input_line && ((recmask & SOUND_MASK_LINE) && !(recmask & SOUND_MASK_MIC)))) {
-               new_input_line = 0;
-               new_input_mask = SOUND_MASK_LINE;
-       } else {
-               new_input_line = 1;
-               new_input_mask = SOUND_MASK_MIC;
-       }
-       harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | 
-                               (new_input_line << GAIN_IS_SHIFT ));
-       harmony_mixer_set_gain();
-       return new_input_mask;
-}
-
-
-/* 
- * give the active outlines
- */
-
-static int harmony_mixer_get_outmask(void)
-{
-       int outmask = 0;
-       
-       if (harmony.current_gain & GAIN_SE_MASK) outmask |= MASK_INTERNAL;
-       if (harmony.current_gain & GAIN_LE_MASK) outmask |= MASK_LINEOUT;
-       if (harmony.current_gain & GAIN_HE_MASK) outmask |= MASK_HEADPHONES;
-       
-       return outmask;
-}
-
-
-static int harmony_mixer_set_outmask(int outmask)
-{
-       if (outmask & MASK_INTERNAL) 
-               harmony.current_gain |= GAIN_SE_MASK;
-       else 
-               harmony.current_gain &= ~GAIN_SE_MASK;
-       
-       if (outmask & MASK_LINEOUT) 
-               harmony.current_gain |= GAIN_LE_MASK;
-       else 
-               harmony.current_gain &= ~GAIN_LE_MASK;
-       
-       if (outmask & MASK_HEADPHONES) 
-               harmony.current_gain |= GAIN_HE_MASK; 
-       else 
-               harmony.current_gain &= ~GAIN_HE_MASK;
-       
-       harmony_mixer_set_gain();
-
-       return (outmask & (MASK_INTERNAL | MASK_LINEOUT | MASK_HEADPHONES));
-}
-
-/*
- * This code is inspired from sb_mixer.c
- */
-
-static int harmony_mixer_ioctl(struct inode * inode, struct file * file,
-               unsigned int cmd, unsigned long arg)
-{
-       int val;
-       int ret;
-
-       if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-                strncpy(info.id, "harmony", sizeof(info.id)-1);
-                strncpy(info.name, "Harmony audio", sizeof(info.name)-1);
-                info.modify_counter = 1; /* ? */
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
-                        return -EFAULT;
-               return 0;
-       }
-       
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
-
-       /* read */
-       val = 0;
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-
-       switch (cmd) {
-       case MIXER_READ(SOUND_MIXER_CAPS):
-               ret = SOUND_CAP_EXCL_INPUT;
-               break;
-       case MIXER_READ(SOUND_MIXER_STEREODEVS):
-               ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN;
-               break;
-               
-       case MIXER_READ(SOUND_MIXER_RECMASK):
-               ret = SOUND_MASK_MIC | SOUND_MASK_LINE;
-               break;
-       case MIXER_READ(SOUND_MIXER_DEVMASK):
-               ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN |
-                       SOUND_MASK_MONITOR;
-               break;
-       case MIXER_READ(SOUND_MIXER_OUTMASK):
-               ret = MASK_INTERNAL | MASK_LINEOUT |
-                       MASK_HEADPHONES;
-               break;
-               
-       case MIXER_WRITE(SOUND_MIXER_RECSRC):
-               ret = harmony_mixer_set_recmask(val);
-               break;
-       case MIXER_READ(SOUND_MIXER_RECSRC):
-               ret = harmony_mixer_get_recmask();
-               break;
-             
-       case MIXER_WRITE(SOUND_MIXER_OUTSRC):
-               ret = harmony_mixer_set_outmask(val);
-               break;
-       case MIXER_READ(SOUND_MIXER_OUTSRC):
-               ret = harmony_mixer_get_outmask();
-               break;
-       
-       case MIXER_WRITE(SOUND_MIXER_VOLUME):
-       case MIXER_WRITE(SOUND_MIXER_IGAIN):
-       case MIXER_WRITE(SOUND_MIXER_MONITOR):
-               ret = harmony_mixer_set_level(cmd & 0xff, val);
-               break;
-
-       case MIXER_READ(SOUND_MIXER_VOLUME):
-       case MIXER_READ(SOUND_MIXER_IGAIN):
-       case MIXER_READ(SOUND_MIXER_MONITOR):
-               ret = harmony_mixer_get_level(cmd & 0xff);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       if (put_user(ret, (int *)arg))
-               return -EFAULT;
-       return 0;
-}
-
-
-static int harmony_mixer_open(struct inode *inode, struct file *file)
-{
-       if (harmony.mixer_open) 
-               return -EBUSY;
-       harmony.mixer_open = 1;
-       return 0;
-}
-
-static int harmony_mixer_release(struct inode *inode, struct file *file)
-{
-       if (!harmony.mixer_open) 
-               return -EBUSY;
-       harmony.mixer_open = 0;
-       return 0;
-}
-
-static struct file_operations harmony_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .open           = harmony_mixer_open,
-       .release        = harmony_mixer_release,
-       .ioctl          = harmony_mixer_ioctl,
-};
-
-
-/*
- * Mute all the output and reset Harmony.
- */
-
-static void __init harmony_mixer_reset(void)
-{
-       harmony.current_gain = GAIN_TOTAL_SILENCE;
-       harmony_mixer_set_gain();
-       harmony_wait_CNTL();
-       gsc_writel(1, &harmony.hpa->reset);
-       mdelay(50);             /* wait 50 ms */
-       gsc_writel(0, &harmony.hpa->reset);
-       harmony.current_gain = GAIN_DEFAULT;
-       harmony_mixer_set_gain();
-}
-
-static int __init harmony_mixer_init(void)
-{
-       /* Register the device file operations */
-       harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1);
-       if (harmony.mixer_unit < 0) {
-               printk(KERN_WARNING PFX "Error Registering Mixer Driver\n");
-               return -EFAULT;
-       }
-  
-       harmony_mixer_reset();
-       harmony.mixer_open = 0;
-       
-       return 0;
-}
-
-
-
-/* 
- * This is the callback that's called by the inventory hardware code 
- * if it finds a match to the registered driver. 
- */
-static int __devinit
-harmony_driver_probe(struct parisc_device *dev)
-{
-       u8      id;
-       u8      rev;
-       u32     cntl;
-       int     ret;
-
-       if (harmony.hpa) {
-               /* We only support one Harmony at this time */
-               printk(KERN_ERR PFX "driver already registered\n");
-               return -EBUSY;
-       }
-
-       if (!dev->irq) {
-               printk(KERN_ERR PFX "no irq found\n");
-               return -ENODEV;
-       }
-
-       /* Set the HPA of harmony */
-       harmony.hpa = (struct harmony_hpa *)dev->hpa.start;
-       harmony.dev = dev;
-
-       /* Grab the ID and revision from the device */
-       id = gsc_readb(&harmony.hpa->id);
-       if ((id | 1) != 0x15) {
-               printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id);
-               return -EBUSY;
-       }
-       cntl = gsc_readl(&harmony.hpa->cntl);
-       rev = (cntl>>20) & 0xff;
-
-       printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
-                       "h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
-                       id, rev, dev->hpa.start, harmony.dev->irq);
-       
-       /* Make sure the control bit isn't set, although I don't think it 
-          ever is. */
-       if (cntl & CNTL_C) {
-               printk(KERN_WARNING PFX "CNTL busy\n");
-               harmony.hpa = 0;
-               return -EBUSY;
-       }
-
-       /* Initialize the memory buffers */
-       if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
-           harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
-           harmony_alloc_buffer(&graveyard, 1) ||
-           harmony_alloc_buffer(&silent, 1)) {
-               ret = -EBUSY;
-               goto out_err;
-       }
-
-       /* Initialize /dev/mixer and /dev/audio  */
-       if ((ret=harmony_mixer_init())) 
-               goto out_err;
-       if ((ret=harmony_audio_init())) 
-               goto out_err;
-
-       return 0;
-
-out_err:
-       harmony.hpa = 0;
-       harmony_free_buffer(&played_buf);
-       harmony_free_buffer(&recorded_buf);
-       harmony_free_buffer(&graveyard);
-       harmony_free_buffer(&silent);
-       return ret;
-}
-
-
-static struct parisc_device_id harmony_tbl[] = {
- /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(parisc, harmony_tbl);
-
-static struct parisc_driver harmony_driver = {
-       .name           = "Lasi Harmony",
-       .id_table       = harmony_tbl,
-       .probe          = harmony_driver_probe,
-};
-
-static int __init init_harmony(void)
-{
-       return register_parisc_driver(&harmony_driver);
-}
-
-static void __exit cleanup_harmony(void)
-{
-       free_irq(harmony.dev->irq, &harmony);
-       unregister_sound_mixer(harmony.mixer_unit);
-       unregister_sound_dsp(harmony.dsp_unit);
-       harmony_free_buffer(&played_buf);
-       harmony_free_buffer(&recorded_buf);
-       harmony_free_buffer(&graveyard);
-       harmony_free_buffer(&silent);
-       unregister_parisc_driver(&harmony_driver);
-}
-
-
-MODULE_AUTHOR("Alex DeVries <alex@onefishtwo.ca>");
-MODULE_DESCRIPTION("Harmony sound driver");
-MODULE_LICENSE("GPL");
-
-module_init(init_harmony);
-module_exit(cleanup_harmony);
-
diff --git a/sound/oss/ics2101.c b/sound/oss/ics2101.c
deleted file mode 100644 (file)
index d5f3be8..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * sound/ics2101.c
- *
- * Driver for the ICS2101 mixer of GUS v3.7.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
- * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init()
- */
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
-                        SOUND_MASK_SYNTH| \
-                        SOUND_MASK_CD | SOUND_MASK_VOLUME)
-
-extern int     *gus_osp;
-extern int      gus_base;
-extern spinlock_t gus_lock;
-static int      volumes[ICS_MIXDEVS];
-static int      left_fix[ICS_MIXDEVS] =
-{1, 1, 1, 2, 1, 2};
-static int      right_fix[ICS_MIXDEVS] =
-{2, 2, 2, 1, 2, 1};
-
-static int scale_vol(int vol)
-{
-       /*
-        *  Experimental volume scaling by Risto Kankkunen.
-        *  This should give smoother volume response than just
-        *  a plain multiplication.
-        */
-        
-       int e;
-
-       if (vol < 0)
-               vol = 0;
-       if (vol > 100)
-               vol = 100;
-       vol = (31 * vol + 50) / 100;
-       e = 0;
-       if (vol)
-       {
-               while (vol < 16)
-               {
-                       vol <<= 1;
-                       e--;
-               }
-               vol -= 16;
-               e += 7;
-       }
-       return ((e << 4) + vol);
-}
-
-static void write_mix(int dev, int chn, int vol)
-{
-       int *selector;
-       unsigned long flags;
-       int ctrl_addr = dev << 3;
-       int attn_addr = dev << 3;
-
-       vol = scale_vol(vol);
-
-       if (chn == CHN_LEFT)
-       {
-               selector = left_fix;
-               ctrl_addr |= 0x00;
-               attn_addr |= 0x02;
-       }
-       else
-       {
-               selector = right_fix;
-               ctrl_addr |= 0x01;
-               attn_addr |= 0x03;
-       }
-
-       spin_lock_irqsave(&gus_lock, flags);
-       outb((ctrl_addr), u_MixSelect);
-       outb((selector[dev]), u_MixData);
-       outb((attn_addr), u_MixSelect);
-       outb(((unsigned char) vol), u_MixData);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int set_volumes(int dev, int vol)
-{
-       int left = vol & 0x00ff;
-       int right = (vol >> 8) & 0x00ff;
-
-       if (left < 0)
-               left = 0;
-       if (left > 100)
-               left = 100;
-       if (right < 0)
-               right = 0;
-       if (right > 100)
-               right = 100;
-
-       write_mix(dev, CHN_LEFT, left);
-       write_mix(dev, CHN_RIGHT, right);
-
-       vol = left + (right << 8);
-       volumes[dev] = vol;
-       return vol;
-}
-
-static int ics2101_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int val;
-       
-       if (((cmd >> 8) & 0xff) == 'M') {
-               if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-                       
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       switch (cmd & 0xff) {
-                       case SOUND_MIXER_RECSRC:
-                               return gus_default_mixer_ioctl(dev, cmd, arg);
-
-                       case SOUND_MIXER_MIC:
-                               val = set_volumes(DEV_MIC, val);
-                               break;
-                               
-                       case SOUND_MIXER_CD:
-                               val = set_volumes(DEV_CD, val);
-                               break;
-
-                       case SOUND_MIXER_LINE:
-                               val = set_volumes(DEV_LINE, val);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = set_volumes(DEV_GF1, val);
-                               break;
-
-                       case SOUND_MIXER_VOLUME:
-                               val = set_volumes(DEV_VOL, val);
-                               break;
-
-                       default:
-                               return -EINVAL;
-                       }
-                       return put_user(val, (int __user *)arg);
-               } else {
-                       switch (cmd & 0xff) {
-                               /*
-                                * Return parameters
-                                */
-                       case SOUND_MIXER_RECSRC:
-                               return gus_default_mixer_ioctl(dev, cmd, arg);
-
-                       case SOUND_MIXER_DEVMASK:
-                               val = MIX_DEVS; 
-                               break;
-
-                       case SOUND_MIXER_STEREODEVS:
-                               val = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC; 
-                               break;
-
-                       case SOUND_MIXER_RECMASK:
-                               val = SOUND_MASK_MIC | SOUND_MASK_LINE; 
-                               break;
-                               
-                       case SOUND_MIXER_CAPS:
-                               val = 0; 
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               val = volumes[DEV_MIC];
-                               break;
-                               
-                       case SOUND_MIXER_LINE:
-                               val = volumes[DEV_LINE];
-                               break;
-
-                       case SOUND_MIXER_CD:
-                               val = volumes[DEV_CD];
-                               break;
-
-                       case SOUND_MIXER_VOLUME:
-                               val = volumes[DEV_VOL];
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = volumes[DEV_GF1]; 
-                               break;
-
-                       default:
-                               return -EINVAL;
-                       }
-                       return put_user(val, (int __user *)arg);
-               }
-       }
-       return -EINVAL;
-}
-
-static struct mixer_operations ics2101_mixer_operations =
-{
-       .owner  = THIS_MODULE,
-       .id     = "ICS2101",
-       .name   = "ICS2101 Multimedia Mixer",
-       .ioctl  = ics2101_mixer_ioctl
-};
-
-int __init ics2101_mixer_init(void)
-{
-       int i;
-       int n;
-
-       if ((n = sound_alloc_mixerdev()) != -1)
-       {
-               mixer_devs[n] = &ics2101_mixer_operations;
-
-               /*
-                * Some GUS v3.7 cards had some channels flipped. Disable
-                * the flipping feature if the model id is other than 5.
-                */
-
-               if (inb(u_MixSelect) != 5)
-               {
-                       for (i = 0; i < ICS_MIXDEVS; i++)
-                               left_fix[i] = 1;
-                       for (i = 0; i < ICS_MIXDEVS; i++)
-                               right_fix[i] = 2;
-               }
-               set_volumes(DEV_GF1, 0x5a5a);
-               set_volumes(DEV_CD, 0x5a5a);
-               set_volumes(DEV_MIC, 0x0000);
-               set_volumes(DEV_LINE, 0x5a5a);
-               set_volumes(DEV_VOL, 0x5a5a);
-               set_volumes(DEV_UNUSED, 0x0000);
-       }
-       return n;
-}
diff --git a/sound/oss/iwmem.h b/sound/oss/iwmem.h
deleted file mode 100644 (file)
index 84745fb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * sound/iwmem.h
- *
- * DRAM size encoding table for AMD Interwave chip.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * Bartlomiej Zolnierkiewicz   : added __initdata to mem_decode
- */
-
-
-#define K 1024
-#define M (1024*K)
-static int mem_decode[][4] __initdata =
-{
-/*     Bank0   Bank1   Bank2   Bank3   Encoding bits   */
-       {256*K, 0,      0,      0},             /*  0 */
-       {256*K, 256*K,  0,      0},             /*  1 */
-       {256*K, 256*K,  256*K,  256*K},         /*  2 */
-       {256*K, 1*M,    0,      0},             /*  3 */
-       {256*K, 1*M,    1*M,    1*M},           /*  4 */
-       {256*K, 256*K,  1*M,    0},             /*  5 */
-       {256*K, 256*K,  1*M,    1*M},           /*  6 */
-       {1*M,   0,      0,      0},             /*  7 */
-       {1*M,   1*M,    0,      0},             /*  8 */
-       {1*M,   1*M,    1*M,    1*M},           /*  9 */
-       {4*M,   0,      0,      0},             /* 10 */
-       {4*M,   4*M,    0,      0},             /* 11 */
-       {4*M,   4*M,    4*M,    4*M}            /* 12 */
-};
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c
deleted file mode 100644 (file)
index aa3c50d..0000000
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * mad16.c
- *
- * Initialization code for OPTi MAD16 compatible audio chips. Including
- *
- *      OPTi 82C928     MAD16           (replaced by C929)
- *      OAK OTI-601D    Mozart
- *      OAK OTI-605    Mozart          (later version with MPU401 Midi)
- *      OPTi 82C929     MAD16 Pro
- *      OPTi 82C930
- *      OPTi 82C924
- *
- * These audio interface chips don't produce sound themselves. They just
- * connect some other components (OPL-[234] and a WSS compatible codec)
- * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
- * also a UART for the MPU-401 mode (not 82C928/Mozart).
- * The Mozart chip appears to be compatible with the 82C928, although later
- * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi
- * port. This port is configured differently to that of the OPTi audio chips.
- *
- *     Changes
- *     
- *     Alan Cox                Clean up, added module selections.
- *
- *     A. Wik                  Added support for Opti924 PnP.
- *                             Improved debugging support.     16-May-1998
- *                             Fixed bug.                      16-Jun-1998
- *
- *      Torsten Duwe            Made Opti924 PnP support non-destructive
- *                                                                     23-Dec-1998
- *
- *     Paul Grayson            Added support for Midi on later Mozart cards.
- *                                                             25-Nov-1999
- *     Christoph Hellwig       Adapted to module_init/module_exit.
- *     Arnaldo C. de Melo      got rid of attach_uart401       21-Sep-2000
- *
- *     Pavel Rabel             Clean up                           Nov-2000
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gameport.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "sb.h"
-#include "mpu401.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int      mad16_conf;
-static int      mad16_cdsel;
-static DEFINE_SPINLOCK(lock);
-
-#define C928   1
-#define MOZART 2
-#define C929   3
-#define C930   4
-#define C924    5
-
-/*
- *    Registers
- *
- *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
- *      All ports are inactive by default. They can be activated by
- *      writing 0xE2 or 0xE3 to the password register. The password is valid
- *      only until the next I/O read or write.
- *
- *      82C930 uses 0xE4 as the password and indirect addressing to access
- *      the config registers.
- */
-
-#define MC0_PORT       0xf8c   /* Dummy port */
-#define MC1_PORT       0xf8d   /* SB address, CD-ROM interface type, joystick */
-#define MC2_PORT       0xf8e   /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
-#define MC3_PORT       0xf8f
-#define PASSWD_REG     0xf8f
-#define MC4_PORT       0xf90
-#define MC5_PORT       0xf91
-#define MC6_PORT       0xf92
-#define MC7_PORT       0xf93
-#define MC8_PORT       0xf94
-#define MC9_PORT       0xf95
-#define MC10_PORT      0xf96
-#define MC11_PORT      0xf97
-#define MC12_PORT      0xf98
-
-static int      board_type = C928;
-
-static int     *mad16_osp;
-static int     c931_detected;  /* minor differences from C930 */
-static char    c924pnp;        /* "     "           "    C924 */
-static int     debug;          /* debugging output */
-
-#ifdef DDB
-#undef DDB
-#endif
-#define DDB(x) do {if (debug) x;} while (0)
-
-static unsigned char mad_read(int port)
-{
-       unsigned long flags;
-       unsigned char tmp;
-
-       spin_lock_irqsave(&lock,flags);
-
-       switch (board_type)     /* Output password */
-       {
-               case C928:
-               case MOZART:
-                       outb((0xE2), PASSWD_REG);
-                       break;
-
-               case C929:
-                       outb((0xE3), PASSWD_REG);
-                       break;
-
-               case C930:
-                       /* outb(( 0xE4),  PASSWD_REG); */
-                       break;
-
-               case C924:
-                       /* the c924 has its ports relocated by -128 if
-                          PnP is enabled  -aw */
-                       if (!c924pnp)
-                               outb((0xE5), PASSWD_REG); else
-                               outb((0xE5), PASSWD_REG - 0x80);
-                       break;
-       }
-
-       if (board_type == C930)
-       {
-               outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
-               tmp = inb(0xe0f);       /* Read from data reg */
-       }
-       else
-               if (!c924pnp)
-                       tmp = inb(port); else
-                       tmp = inb(port-0x80);
-       spin_unlock_irqrestore(&lock,flags);
-
-       return tmp;
-}
-
-static void mad_write(int port, int value)
-{
-       unsigned long   flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       switch (board_type)     /* Output password */
-       {
-               case C928:
-               case MOZART:
-                       outb((0xE2), PASSWD_REG);
-                       break;
-
-               case C929:
-                       outb((0xE3), PASSWD_REG);
-                       break;
-
-               case C930:
-                       /* outb(( 0xE4),  PASSWD_REG); */
-                       break;
-
-               case C924:
-                       if (!c924pnp)
-                               outb((0xE5), PASSWD_REG); else
-                               outb((0xE5), PASSWD_REG - 0x80);
-                       break;
-       }
-
-       if (board_type == C930)
-       {
-               outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
-               outb(((unsigned char) (value & 0xff)), 0xe0f);
-       }
-       else
-               if (!c924pnp)
-                       outb(((unsigned char) (value & 0xff)), port); else
-                       outb(((unsigned char) (value & 0xff)), port-0x80);
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init detect_c930(void)
-{
-       unsigned char   tmp = mad_read(MC1_PORT);
-
-       if ((tmp & 0x06) != 0x06)
-       {
-               DDB(printk("Wrong C930 signature (%x)\n", tmp));
-               /* return 0; */
-       }
-       mad_write(MC1_PORT, 0);
-
-       if (mad_read(MC1_PORT) != 0x06)
-       {
-               DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
-               /* return 0; */
-       }
-       mad_write(MC1_PORT, tmp);       /* Restore bits */
-
-       mad_write(MC7_PORT, 0);
-       if ((tmp = mad_read(MC7_PORT)) != 0)
-       {
-               DDB(printk("MC7 not writable (%x)\n", tmp));
-               return 0;
-       }
-       mad_write(MC7_PORT, 0xcb);
-       if ((tmp = mad_read(MC7_PORT)) != 0xcb)
-       {
-               DDB(printk("MC7 not writable2 (%x)\n", tmp));
-               return 0;
-       }
-
-       tmp = mad_read(MC0_PORT+18);
-       if (tmp == 0xff || tmp == 0x00)
-               return 1;
-       /* We probably have a C931 */
-       DDB(printk("Detected C931 config=0x%02x\n", tmp));
-       c931_detected = 1;
-
-       /*
-         * We cannot configure the chip if it is in PnP mode.
-         * If we have a CSN assigned (bit 8 in MC13) we first try
-         * a software reset, then a software power off, finally
-         * Clearing PnP mode. The last option is not
-        * Bit 8 in MC13 
-         */
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-
-       /* Software reset */
-       mad_write(MC9_PORT, 0x02);
-       mad_write(MC9_PORT, 0x00);
-
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-       
-       /* Power off, and on again */
-       mad_write(MC9_PORT, 0xc2);
-       mad_write(MC9_PORT, 0xc0);
-
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-       
-#if 0  
-       /* Force off PnP mode. This is not recommended because
-        * the PnP bios will not recognize the chip on the next
-        * warm boot and may assignd different resources to other
-        * PnP/PCI cards.
-        */
-       mad_write(MC0_PORT+17, 0x04);
-#endif
-       return 1;
-}
-
-static int __init detect_mad16(void)
-{
-       unsigned char tmp, tmp2, bit;
-       int i, port;
-
-       /*
-        * Check that reading a register doesn't return bus float (0xff)
-        * when the card is accessed using password. This may fail in case
-        * the card is in low power mode. Normally at least the power saving
-        * mode bit should be 0.
-        */
-
-       if ((tmp = mad_read(MC1_PORT)) == 0xff)
-       {
-               DDB(printk("MC1_PORT returned 0xff\n"));
-               return 0;
-       }
-       for (i = 0xf8d; i <= 0xf98; i++)
-               if (!c924pnp)
-                       DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
-               else
-                       DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));
-
-       if (board_type == C930)
-               return detect_c930();
-
-       /*
-        * Now check that the gate is closed on first I/O after writing
-        * the password. (This is how a MAD16 compatible card works).
-        */
-
-       if ((tmp2 = inb(MC1_PORT)) == tmp)      /* It didn't close */
-       {
-               DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
-               return 0;
-       }
-
-       bit  = (c924pnp) ?     0x20 : 0x80;
-       port = (c924pnp) ? MC2_PORT : MC1_PORT;
-
-       tmp = mad_read(port);
-       mad_write(port, tmp ^ bit);     /* Toggle a bit */
-       if ((tmp2 = mad_read(port)) != (tmp ^ bit))     /* Compare the bit */
-       {
-               mad_write(port, tmp);   /* Restore */
-               DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
-               return 0;
-       }
-       mad_write(port, tmp);   /* Restore */
-       return 1;               /* Bingo */
-}
-
-static int __init wss_init(struct address_info *hw_config)
-{
-       /*
-        * Check if the IO port returns valid signature. The original MS Sound
-        * system returns 0x04 while some cards (AudioTrix Pro for example)
-        * return 0x00.
-        */
-
-       if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
-           (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
-       {
-               DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
-               return 0;
-       }
-       /*
-        * Check that DMA0 is not in use with a 8 bit board.
-        */
-       if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
-       {
-               printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
-               return 0;
-       }
-       if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80)
-               printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
-       return 1;
-}
-
-static void __init init_c930(struct address_info *hw_config, int base)
-{
-       unsigned char cfg = 0;
-
-       cfg |= (0x0f & mad16_conf);
-
-       if(c931_detected)
-       {
-               /* Bit 0 has reversd meaning. Bits 1 and 2 sese
-                  reversed on write.
-                  Support only IDE cdrom. IDE port programmed
-                  somewhere else. */
-               cfg =  (cfg & 0x09) ^ 0x07;
-       }
-       cfg |= base << 4;
-       mad_write(MC1_PORT, cfg);
-
-       /* MC2 is CD configuration. Don't touch it. */
-
-       mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
-
-       /* bit 2 of MC4 reverses it's meaning between the C930
-          and the C931. */
-       cfg = c931_detected ? 0x04 : 0x00;
-
-       if(mad16_cdsel & 0x20)
-               mad_write(MC4_PORT, 0x62|cfg);  /* opl4 */
-       else
-               mad_write(MC4_PORT, 0x52|cfg);  /* opl3 */
-
-       mad_write(MC5_PORT, 0x3C);      /* Init it into mode2 */
-       mad_write(MC6_PORT, 0x02);      /* Enable WSS, Disable MPU and SB */
-       mad_write(MC7_PORT, 0xCB);
-       mad_write(MC10_PORT, 0x11);
-}
-
-static int __init chip_detect(void)
-{
-       int i;
-
-       /*
-        *    Then try to detect with the old password
-        */
-       board_type = C924;
-
-       DDB(printk("Detect using password = 0xE5\n"));
-       
-       if (detect_mad16()) {
-               return 1;
-       }
-       
-       board_type = C928;
-
-       DDB(printk("Detect using password = 0xE2\n"));
-
-       if (detect_mad16())
-       {
-               unsigned char model;
-
-               if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
-                       DDB(printk("mad16.c: Mozart detected\n"));
-                       board_type = MOZART;
-               } else {
-                       DDB(printk("mad16.c: 82C928 detected???\n"));
-                       board_type = C928;
-               }
-               return 1;
-       }
-
-       board_type = C929;
-
-       DDB(printk("Detect using password = 0xE3\n"));
-
-       if (detect_mad16())
-       {
-               DDB(printk("mad16.c: 82C929 detected\n"));
-               return 1;
-       }
-
-       if (inb(PASSWD_REG) != 0xff)
-               return 0;
-
-       /*
-        * First relocate MC# registers to 0xe0e/0xe0f, disable password 
-        */
-
-       outb((0xE4), PASSWD_REG);
-       outb((0x80), PASSWD_REG);
-
-       board_type = C930;
-
-       DDB(printk("Detect using password = 0xE4\n"));
-
-       for (i = 0xf8d; i <= 0xf93; i++)
-               DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-
-        if(detect_mad16()) {
-               DDB(printk("mad16.c: 82C930 detected\n"));
-               return 1;
-       }
-
-       /* The C931 has the password reg at F8D */
-       outb((0xE4), 0xF8D);
-       outb((0x80), 0xF8D);
-       DDB(printk("Detect using password = 0xE4 for C931\n"));
-
-       if (detect_mad16()) {
-               return 1;
-       }
-
-       board_type = C924;
-       c924pnp++;
-       DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
-       if (detect_mad16()) {
-               DDB(printk("mad16.c: 82C924 PnP detected\n"));
-               return 1;
-       }
-       
-       c924pnp=0;
-
-       return 0;
-}
-
-static int __init probe_mad16(struct address_info *hw_config)
-{
-       int i;
-       unsigned char tmp;
-       unsigned char cs4231_mode = 0;
-
-       int ad_flags = 0;
-
-       signed char bits;
-
-       static char     dma_bits[4] = {
-               1, 2, 0, 3
-       };
-
-       int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
-       int dma = hw_config->dma, dma2 = hw_config->dma2;
-       unsigned char dma2_bit = 0;
-       int base;
-       struct resource *ports;
-
-       mad16_osp = hw_config->osp;
-
-       switch (hw_config->io_base) {
-       case 0x530:
-               base = 0;
-               break;
-       case 0xe80:
-               base = 1;
-               break;
-       case 0xf40:
-               base = 2;
-               break;
-       case 0x604:
-               base = 3;
-               break;
-       default:
-               printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
-               return 0;
-       }
-
-       if (dma != 0 && dma != 1 && dma != 3) {
-               printk(KERN_ERR "MSS: Bad DMA %d\n", dma);
-               return 0;
-       }
-
-       /*
-        *    Check that all ports return 0xff (bus float) when no password
-        *      is written to the password register.
-        */
-
-       DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
-       if (!chip_detect())
-               return 0;
-
-       switch (hw_config->irq) {
-       case 7:
-               bits = 8;
-               break;
-       case 9:
-               bits = 0x10;
-               break;
-       case 10:
-               bits = 0x18;
-               break;
-       case 12:
-               bits = 0x20;
-               break;
-       case 5: /* Also IRQ5 is possible on C930 */
-               if (board_type == C930 || c924pnp) {
-                       bits = 0x28;
-                       break;
-               }
-       default:
-               printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-
-       ports = request_region(hw_config->io_base + 4, 4, "ad1848");
-       if (!ports) {
-               printk(KERN_ERR "MSS: I/O port conflict\n");
-               return 0;
-       }
-       if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) {
-               release_region(hw_config->io_base + 4, 4);
-               printk(KERN_ERR "MSS: I/O port conflict\n");
-               return 0;
-       }
-
-       if (board_type == C930) {
-               init_c930(hw_config, base);
-               goto got_it;
-       }
-
-       for (i = 0xf8d; i <= 0xf93; i++) {
-               if (!c924pnp)
-                       DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-               else
-                       DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));
-       }
-
-/*
- * Set the WSS address
- */
-
-       tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80;       /* Enable WSS, Disable SB */
-       tmp |= base << 4;       /* WSS port select bits */
-
-       /*
-        * Set optional CD-ROM and joystick settings.
-        */
-
-       tmp &= ~0x0f;
-       tmp |= (mad16_conf & 0x0f);     /* CD-ROM and joystick bits */
-       mad_write(MC1_PORT, tmp);
-
-       tmp = mad16_cdsel;
-       mad_write(MC2_PORT, tmp);
-       mad_write(MC3_PORT, 0xf0);      /* Disable SB */
-
-       if (board_type == C924) /* Specific C924 init values */
-       {
-               mad_write(MC4_PORT, 0xA0);
-               mad_write(MC5_PORT, 0x05);
-               mad_write(MC6_PORT, 0x03);
-       }
-       if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-               goto fail;
-
-       if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
-               cs4231_mode = 0x02;     /* CS4248/CS4231 sync delay switch */
-
-       if (board_type == C929)
-       {
-               mad_write(MC4_PORT, 0xa2);
-               mad_write(MC5_PORT, 0xA5 | cs4231_mode);
-               mad_write(MC6_PORT, 0x03);      /* Disable MPU401 */
-       }
-       else
-       {
-               mad_write(MC4_PORT, 0x02);
-               mad_write(MC5_PORT, 0x30 | cs4231_mode);
-       }
-
-       for (i = 0xf8d; i <= 0xf93; i++) {
-               if (!c924pnp)
-                       DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
-               else
-                       DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
-       }
-
-got_it:
-       ad_flags = 0;
-       if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-               goto fail;
-
-       if (!wss_init(hw_config))
-               goto fail;
-
-       /*
-        * Set the IRQ and DMA addresses.
-        */
-       
-       outb((bits | 0x40), config_port);
-       if ((inb(version_port) & 0x40) == 0)
-               printk(KERN_ERR "[IRQ Conflict?]\n");
-
-       /*
-        * Handle the capture DMA channel
-        */
-
-       if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
-       {
-               if (!((dma == 0 && dma2 == 1) ||
-                       (dma == 1 && dma2 == 0) ||
-                       (dma == 3 && dma2 == 0)))
-               {               /* Unsupported combination. Try to swap channels */
-                       int tmp = dma;
-
-                       dma = dma2;
-                       dma2 = tmp;
-               }
-               if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
-                       (dma == 3 && dma2 == 0))
-               {
-                       dma2_bit = 0x04;        /* Enable capture DMA */
-               }
-               else
-               {
-                       printk("MAD16: Invalid capture DMA\n");
-                       dma2 = dma;
-               }
-       }
-       else dma2 = dma;
-
-       outb((bits | dma_bits[dma] | dma2_bit), config_port);   /* Write IRQ+DMA setup */
-
-       hw_config->slots[0] = ad1848_init("mad16 WSS", ports,
-                                         hw_config->irq,
-                                         dma,
-                                         dma2, 0,
-                                         hw_config->osp,
-                                         THIS_MODULE);
-       return 1;
-
-fail:
-       release_region(hw_config->io_base + 4, 4);
-       release_region(hw_config->io_base, 4);
-       return 0;
-}
-
-static int __init probe_mad16_mpu(struct address_info *hw_config)
-{
-       unsigned char tmp;
-
-       if (board_type < C929)  /* Early chip. No MPU support. Just SB MIDI */
-       {
-
-#ifdef CONFIG_MAD16_OLDCARD
-
-               tmp = mad_read(MC3_PORT);
-
-               /* 
-                * MAD16 SB base is defined by the WSS base. It cannot be changed 
-                * alone.
-                * Ignore configured I/O base. Use the active setting. 
-                */
-
-               if (mad_read(MC1_PORT) & 0x20)
-                       hw_config->io_base = 0x240;
-               else
-                       hw_config->io_base = 0x220;
-
-               switch (hw_config->irq)
-               {
-                       case 5:
-                               tmp = (tmp & 0x3f) | 0x80;
-                               break;
-                       case 7:
-                               tmp = (tmp & 0x3f);
-                               break;
-                       case 11:
-                               tmp = (tmp & 0x3f) | 0x40;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
-                               return 0;
-               }
-
-               mad_write(MC3_PORT, tmp | 0x04);
-               hw_config->driver_use_1 = SB_MIDI_ONLY;
-               if (!request_region(hw_config->io_base, 16, "soundblaster"))
-                       return 0;
-               if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
-                       release_region(hw_config->io_base, 16);
-                       return 0;
-               }
-
-               if (mad_read(MC1_PORT) & 0x20)
-                       hw_config->io_base = 0x240;
-               else
-                       hw_config->io_base = 0x220;
-
-               hw_config->name = "Mad16/Mozart";
-               sb_dsp_init(hw_config, THIS_MODULE);
-               return 1;
-#else
-               /* assuming all later Mozart cards are identified as
-                * either 82C928 or Mozart. If so, following code attempts
-                * to set MPU register. TODO - add probing
-                */
-
-               tmp = mad_read(MC8_PORT);
-
-               switch (hw_config->irq)
-               {
-                       case 5:
-                               tmp |= 0x08;
-                               break;
-                       case 7:
-                               tmp |= 0x10;
-                               break;
-                       case 9:
-                               tmp |= 0x18;
-                               break;
-                       case 10:
-                               tmp |= 0x20;
-                               break;
-                       case 11:
-                               tmp |= 0x28;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
-                               return 0;
-               }
-
-               switch (hw_config->io_base)
-               {
-                       case 0x300:
-                               tmp |= 0x01;
-                               break;
-                       case 0x310:
-                               tmp |= 0x03;
-                               break;
-                       case 0x320:
-                               tmp |= 0x05;
-                               break;
-                       case 0x330:
-                               tmp |= 0x07;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
-                               return 0;
-               }
-
-               mad_write(MC8_PORT, tmp);       /* write MPU port parameters */
-               goto probe_401;
-#endif
-       }
-       tmp = mad_read(MC6_PORT) & 0x83;
-       tmp |= 0x80;            /* MPU-401 enable */
-
-       /* Set the MPU base bits */
-
-       switch (hw_config->io_base)
-       {
-               case 0x300:
-                       tmp |= 0x60;
-                       break;
-               case 0x310:
-                       tmp |= 0x40;
-                       break;
-               case 0x320:
-                       tmp |= 0x20;
-                       break;
-               case 0x330:
-                       tmp |= 0x00;
-                       break;
-               default:
-                       printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
-                       return 0;
-       }
-
-       /* Set the MPU IRQ bits */
-
-       switch (hw_config->irq)
-       {
-               case 5:
-                       tmp |= 0x10;
-                       break;
-               case 7:
-                       tmp |= 0x18;
-                       break;
-               case 9:
-                       tmp |= 0x00;
-                       break;
-               case 10:
-                       tmp |= 0x08;
-                       break;
-               default:
-                       printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
-                       break;
-       }
-                       
-       mad_write(MC6_PORT, tmp);       /* Write MPU401 config */
-
-#ifndef CONFIG_MAD16_OLDCARD
-probe_401:
-#endif
-       hw_config->driver_use_1 = SB_MIDI_ONLY;
-       hw_config->name = "Mad16/Mozart";
-       return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_mad16(struct address_info *hw_config)
-{
-       ad1848_unload(hw_config->io_base + 4,
-                       hw_config->irq,
-                       hw_config->dma,
-                       hw_config->dma2, 0);
-       release_region(hw_config->io_base, 4);
-       sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static void __exit unload_mad16_mpu(struct address_info *hw_config)
-{
-#ifdef CONFIG_MAD16_OLDCARD
-       if (board_type < C929)  /* Early chip. No MPU support. Just SB MIDI */
-       {
-               sb_dsp_unload(hw_config, 0);
-               return;
-       }
-#endif
-
-       unload_uart401(hw_config);
-}
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int found_mpu;
-
-static int __initdata mpu_io = 0;
-static int __initdata mpu_irq = 0;
-static int __initdata io = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1; /* Set this for modules that need it */
-static int __initdata irq = -1;
-static int __initdata cdtype = 0;
-static int __initdata cdirq = 0;
-static int __initdata cdport = 0x340;
-static int __initdata cddma = -1;
-static int __initdata opl4 = 0;
-static int __initdata joystick = 0;
-
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-module_param(io, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(irq, int, 0);
-module_param(cdtype, int, 0);
-module_param(cdirq, int, 0);
-module_param(cdport, int, 0);
-module_param(cddma, int, 0);
-module_param(opl4, int, 0);
-module_param(joystick, bool, 0);
-module_param(debug, bool, 0644);
-
-static int __initdata dma_map[2][8] =
-{
-       {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
-       {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
-};
-
-static int __initdata irq_map[16] =
-{
-       0x00, -1, -1, 0x0A,
-       -1, 0x04, -1, 0x08,
-       -1, 0x10, 0x14, 0x18,
-       -1, -1, -1, -1
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static struct gameport *gameport;
-
-static int __devinit mad16_register_gameport(int io_port)
-{
-       if (!request_region(io_port, 1, "mad16 gameport")) {
-               printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
-               return -EBUSY;
-       }
-
-       gameport = gameport_allocate_port();
-       if (!gameport) {
-               printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
-               release_region(io_port, 1);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gameport, "MAD16 Gameport");
-       gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
-       gameport->io = io_port;
-
-       gameport_register_port(gameport);
-
-       return 0;
-}
-
-static inline void mad16_unregister_gameport(void)
-{
-       if (gameport) {
-               /* the gameport was initialized so we must free it up */
-               gameport_unregister_port(gameport);
-               gameport = NULL;
-               release_region(0x201, 1);
-       }
-}
-#else
-static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
-static inline void mad16_unregister_gameport(void) { }
-#endif
-
-static int __devinit init_mad16(void)
-{
-       int dmatype = 0;
-
-       printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       printk(KERN_INFO "CDROM ");
-       switch (cdtype)
-       {
-               case 0x00:
-                       printk("Disabled");
-                       cdirq = 0;
-                       break;
-               case 0x02:
-                       printk("Sony CDU31A");
-                       dmatype = 1;
-                       if(cddma == -1) cddma = 3;
-                       break;
-               case 0x04:
-                       printk("Mitsumi");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               case 0x06:
-                       printk("Panasonic Lasermate");
-                       dmatype = 1;
-                       if(cddma == -1) cddma = 3;
-                       break;
-               case 0x08:
-                       printk("Secondary IDE");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               case 0x0A:
-                       printk("Primary IDE");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               default:
-                       printk("\n");
-                       printk(KERN_ERR "Invalid CDROM type\n");
-                       return -EINVAL;
-       }
-
-       /*
-        *    Build the config words
-        */
-
-       mad16_conf = (joystick ^ 1) | cdtype;
-       mad16_cdsel = 0;
-       if (opl4)
-               mad16_cdsel |= 0x20;
-
-       if(cdtype){
-               if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
-               {
-                       printk("\n");
-                       printk(KERN_ERR "Invalid CDROM DMA\n");
-                       return -EINVAL;
-               }
-               if (cddma)
-                       printk(", DMA %d", cddma);
-               else
-                       printk(", no DMA");
-
-               if (!cdirq)
-                       printk(", no IRQ");
-               else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
-               {
-                       printk(", invalid IRQ (disabling)");
-                       cdirq = 0;
-               }
-               else printk(", IRQ %d", cdirq);
-
-               mad16_cdsel |= dma_map[dmatype][cddma];
-
-               if (cdtype < 0x08)
-               {
-                       switch (cdport)
-                       {
-                               case 0x340:
-                                       mad16_cdsel |= 0x00;
-                                       break;
-                               case 0x330:
-                                       mad16_cdsel |= 0x40;
-                                       break;
-                               case 0x360:
-                                       mad16_cdsel |= 0x80;
-                                       break;
-                               case 0x320:
-                                       mad16_cdsel |= 0xC0;
-                                       break;
-                               default:
-                                       printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
-                                       return -EINVAL;
-                       }
-               }
-               mad16_cdsel |= irq_map[cdirq];
-       }
-
-       printk(".\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma16;
-
-       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-               printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
-               return -EINVAL;
-       }
-
-       if (!request_region(MC0_PORT, 12, "mad16"))
-               return -EBUSY;
-
-       if (!probe_mad16(&cfg)) {
-               release_region(MC0_PORT, 12);
-               return -ENODEV;
-       }
-
-       cfg_mpu.io_base = mpu_io;
-       cfg_mpu.irq = mpu_irq;
-
-       found_mpu = probe_mad16_mpu(&cfg_mpu);
-
-       if (joystick)
-               mad16_register_gameport(0x201);
-
-       return 0;
-}
-
-static void __exit cleanup_mad16(void)
-{
-       if (found_mpu)
-               unload_mad16_mpu(&cfg_mpu);
-       mad16_unregister_gameport();
-       unload_mad16(&cfg);
-       release_region(MC0_PORT, 12);
-}
-
-module_init(init_mad16);
-module_exit(cleanup_mad16);
-
-#ifndef MODULE
-static int __init setup_mad16(char *str)
-{
-       /* io, irq */
-       int ints[8];
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       io       = ints[1];
-       irq      = ints[2];
-       dma      = ints[3];
-       dma16    = ints[4];
-       mpu_io   = ints[5];
-       mpu_irq  = ints[6];
-       joystick = ints[7];
-
-       return 1;
-}
-
-__setup("mad16=", setup_mad16);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
deleted file mode 100644 (file)
index 1d98d10..0000000
+++ /dev/null
@@ -1,3686 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.[23].x
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *     (c) Copyright 1999       Alan Cox <alan.cox@linux.org>
- *
- *     Based heavily on SonicVibes.c:
- *      Copyright (C) 1998-1999  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *     Heavily modified by Zach Brown <zab@zabbo.net> based on lunch
- *     with ESS engineers.  Many thanks to Howard Kim for providing 
- *     contacts and hardware.  Honorable mention goes to Eric 
- *     Brombaugh for all sorts of things.  Best regards to the 
- *     proprietors of Hack Central for fine lodging.
- *
- *  Supported devices:
- *  /dev/dsp0-3    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *
- *  Hardware Description
- *
- *     A working Maestro setup contains the Maestro chip wired to a 
- *     codec or 2.  In the Maestro we have the APUs, the ASSP, and the
- *     Wavecache.  The APUs can be though of as virtual audio routing
- *     channels.  They can take data from a number of sources and perform
- *     basic encodings of the data.  The wavecache is a storehouse for
- *     PCM data.  Typically it deals with PCI and interracts with the
- *     APUs.  The ASSP is a wacky DSP like device that ESS is loth
- *     to release docs on.  Thankfully it isn't required on the Maestro
- *     until you start doing insane things like FM emulation and surround
- *     encoding.  The codecs are almost always AC-97 compliant codecs, 
- *     but it appears that early Maestros may have had PT101 (an ESS
- *     part?) wired to them.  The only real difference in the Maestro
- *     families is external goop like docking capability, memory for
- *     the ASSP, and initialization differences.
- *
- *  Driver Operation
- *
- *     We only drive the APU/Wavecache as typical DACs and drive the
- *     mixers in the codecs.  There are 64 APUs.  We assign 6 to each
- *     /dev/dsp? device.  2 channels for output, and 4 channels for
- *     input.
- *
- *     Each APU can do a number of things, but we only really use
- *     3 basic functions.  For playback we use them to convert PCM
- *     data fetched over PCI by the wavecahche into analog data that
- *     is handed to the codec.  One APU for mono, and a pair for stereo.
- *     When in stereo, the combination of smarts in the APU and Wavecache
- *     decide which wavecache gets the left or right channel.
- *
- *     For record we still use the old overly mono system.  For each in
- *     coming channel the data comes in from the codec, through a 'input'
- *     APU, through another rate converter APU, and then into memory via
- *     the wavecache and PCI.  If its stereo, we mash it back into LRLR in
- *     software.  The pass between the 2 APUs is supposedly what requires us
- *     to have a 512 byte buffer sitting around in wavecache/memory.
- *
- *     The wavecache makes our life even more fun.  First off, it can
- *     only address the first 28 bits of PCI address space, making it
- *     useless on quite a few architectures.  Secondly, its insane.
- *     It claims to fetch from 4 regions of PCI space, each 4 meg in length.
- *     But that doesn't really work.  You can only use 1 region.  So all our
- *     allocations have to be in 4meg of each other.  Booo.  Hiss.
- *     So we have a module parameter, dsps_order, that is the order of
- *     the number of dsps to provide.  All their buffer space is allocated
- *     on open time.  The sonicvibes OSS routines we inherited really want
- *     power of 2 buffers, so we have all those next to each other, then
- *     512 byte regions for the recording wavecaches.  This ends up
- *     wasting quite a bit of memory.  The only fixes I can see would be 
- *     getting a kernel allocator that could work in zones, or figuring out
- *     just how to coerce the WP into doing what we want.
- *
- *     The indirection of the various registers means we have to spinlock
- *     nearly all register accesses.  We have the main register indirection
- *     like the wave cache, maestro registers, etc.  Then we have beasts
- *     like the APU interface that is indirect registers gotten at through
- *     the main maestro indirection.  Ouch.  We spinlock around the actual
- *     ports on a per card basis.  This means spinlock activity at each IO
- *     operation, but the only IO operation clusters are in non critical 
- *     paths and it makes the code far easier to follow.  Interrupts are
- *     blocked while holding the locks because the int handler has to
- *     get at some of them :(.  The mixer interface doesn't, however.
- *     We also have an OSS state lock that is thrown around in a few
- *     places.
- *
- *     This driver has brute force APM suspend support.  We catch suspend
- *     notifications and stop all work being done on the chip.  Any people
- *     that try between this shutdown and the real suspend operation will
- *     be put to sleep.  When we resume we restore our software state on
- *     the chip and wake up the people that were using it.  The code thats
- *     being used now is quite dirty and assumes we're on a uni-processor
- *     machine.  Much of it will need to be cleaned up for SMP ACPI or 
- *     similar.
- *
- *     We also pay attention to PCI power management now.  The driver
- *     will power down units of the chip that it knows aren't needed.
- *     The WaveProcessor and company are only powered on when people
- *     have /dev/dsp*s open.  On removal the driver will
- *     power down the maestro entirely.  There could still be
- *     trouble with BIOSen that magically change power states 
- *     themselves, but we'll see.  
- *     
- * History
- *  v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de>
- *      Ported to Linux 2.4 PCI API. Some clean ups, global devs list
- *      removed (now using pci device driver data).
- *      PM needs to be polished still. Bumped version.
- *  (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu>
- *      Add support for 978 docking and basic hardware volume control
- *  (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com>
- *     Add clocking= for people with seriously warped hardware
- *  (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *     add __init to maestro_ac97_init() and maestro_install()
- *  (still based on v0.14) Mar 29 2000 - Zach Brown <zab@redhat.com>
- *     move to 2.3 power management interface, which
- *             required hacking some suspend/resume/check paths 
- *     make static compilation work
- *  v0.14 - Jan 28 2000 - Zach Brown <zab@redhat.com>
- *     add PCI power management through ACPI regs.
- *     we now shut down on machine reboot/halt
- *     leave scary PCI config items alone (isa stuff, mostly)
- *     enable 1921s, it seems only mine was broke.
- *     fix swapped left/right pcm dac.  har har.
- *     up bob freq, increase buffers, fix pointers at underflow
- *     silly compilation problems
- *  v0.13 - Nov 18 1999 - Zach Brown <zab@redhat.com>
- *     fix nec Versas?  man would that be cool.
- *  v0.12 - Nov 12 1999 - Zach Brown <zab@redhat.com>
- *     brown bag volume max fix..
- *  v0.11 - Nov 11 1999 - Zach Brown <zab@redhat.com>
- *     use proper stereo apu decoding, mmap/write should work.
- *     make volume sliders more useful, tweak rate calculation.
- *     fix lame 8bit format reporting bug.  duh. apm apu saving buglet also
- *     fix maestro 1 clock freq "bug", remove pt101 support
- *  v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com>
- *     aha, so, sometimes the WP writes a status word to offset 0
- *       from one of the PCMBARs.  rearrange allocation accordingly..
- *       cheers again to Eric for being a good hacker in investigating this.
- *     Jeroen Hoogervorst submits 7500 fix out of nowhere.  yay.  :)
- *  v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com>
- *     added APM support.
- *     re-order something such that some 2Es now work.  Magic!
- *     new codec reset routine.  made some codecs come to life.
- *     fix clear_advance, sync some control with ESS.
- *     now write to all base regs to be paranoid.
- *  v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com>
- *     Fix initial buflen bug.  I am so smart.  also smp compiling..
- *     I owe Eric yet another beer: fixed recmask, igain, 
- *       muting, and adc sync consistency.  Go Team.
- *  v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com>
- *     tweak adc/dac, formating, and stuff to allow full duplex
- *     allocate dsps memory at open() so we can fit in the wavecache window
- *     fix wavecache braindamage.  again.  no more scribbling?
- *     fix ess 1921 codec bug on some laptops.
- *     fix dumb pci scanning bug
- *     started 2.3 cleanup, redid spinlocks, little cleanups
- *  v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com>
- *     fix wavecache thinkos.  limit to 1 /dev/dsp.
- *     eric is wearing his thinking toque this week.
- *             spotted apu mode bugs and gain ramping problem
- *     don't touch weird mixer regs, make recmask optional
- *     fixed igain inversion, defaults for mixers, clean up rec_start
- *     make mono recording work.
- *     report subsystem stuff, please send reports.
- *     littles: parallel out, amp now
- *  v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com>
- *     merged and fixed up Eric's initial recording code
- *     munged format handling to catch misuse, needs rewrite.
- *     revert ring bus init, fixup shared int, add pci busmaster setting
- *     fix mixer oss interface, fix mic mute and recmask
- *     mask off unsupported mixers, reset with all 1s, modularize defaults
- *     make sure bob is running while we need it
- *     got rid of device limit, initial minimal apm hooks
- *     pull out dead code/includes, only allow multimedia/audio maestros
- *  v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com>
- *     copied memory leak fix from sonicvibes driver
- *     different ac97 reset, play with 2.0 ac97, simplify ring bus setup
- *     bob freq code, region sanity, jitter sync fix; all from Eric 
- *
- * TODO
- *     fix bob frequency
- *     endianness
- *     do smart things with ac97 2.0 bits.
- *     dual codecs
- *     leave 54->61 open
- *
- *     it also would be fun to have a mode that would not use pci dma at all
- *     but would copy into the wavecache on board memory and use that 
- *     on architectures that don't like the maestro's pci dma ickiness.
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/current.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "maestro.h"
-
-static struct pci_driver maestro_pci_driver;
-
-/* --------------------------------------------------------------------- */
-
-#define M_DEBUG 1
-
-#ifdef M_DEBUG
-static int debug;
-#define M_printk(args...) {if (debug) printk(args);}
-#else
-#define M_printk(x)
-#endif
-
-/* we try to setup 2^(dsps_order) /dev/dsp devices */
-static int dsps_order;
-/* whether or not we mess around with power management */
-static int use_pm=2; /* set to 1 for force */
-/* clocking for broken hardware - a few laptops seem to use a 50Khz clock
-       ie insmod with clocking=50000 or so */
-       
-static int clocking=48000;
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
-MODULE_DESCRIPTION("ESS Maestro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, bool, 0644);
-#endif
-module_param(dsps_order, int, 0);
-module_param(use_pm, int, 0);
-module_param(clocking, int, 0);
-
-/* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.15"
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS                 0x125D
-#define PCI_DEVICE_ID_ESS_ESS1968      0x1968          /* Maestro 2    */
-#define PCI_DEVICE_ID_ESS_ESS1978              0x1978          /* Maestro 2E   */
-
-#define PCI_VENDOR_ESS_OLD             0x1285          /* Platform Tech, 
-                                               the people the maestro 
-                                               was bought from */
-#define PCI_DEVICE_ID_ESS_ESS0100      0x0100          /* maestro 1 */
-#endif /* PCI_VENDOR_ESS */
-
-#define ESS_CHAN_HARD          0x100
-
-/* NEC Versas ? */
-#define NEC_VERSA_SUBID1       0x80581033
-#define NEC_VERSA_SUBID2       0x803c1033
-
-
-/* changed so that I could actually find all the
-       references and fix them up.  it's a little more readable now. */
-#define ESS_FMT_STEREO 0x01
-#define ESS_FMT_16BIT  0x02
-#define ESS_FMT_MASK   0x03
-#define ESS_DAC_SHIFT  0   
-#define ESS_ADC_SHIFT  4
-
-#define ESS_STATE_MAGIC                0x125D1968
-#define ESS_CARD_MAGIC         0x19283746
-
-#define DAC_RUNNING            1
-#define ADC_RUNNING            2
-
-#define MAX_DSP_ORDER  2
-#define MAX_DSPS       (1<<MAX_DSP_ORDER)
-#define NR_DSPS                (1<<dsps_order)
-#define NR_IDRS                32
-
-#define NR_APUS                64
-#define NR_APU_REGS    16
-
-/* acpi states */
-enum {
-       ACPI_D0=0,
-       ACPI_D1,
-       ACPI_D2,
-       ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ     ( 1 << 15)
-#define ACPI_24MHZ     ( 1 << 14)
-#define ACPI_978       ( 1 << 13)
-#define ACPI_SPDIF     ( 1 << 12)
-#define ACPI_GLUE      ( 1 << 11)
-#define ACPI__10       ( 1 << 10) /* reserved */
-#define ACPI_PCIINT    ( 1 << 9)
-#define ACPI_HV                ( 1 << 8) /* hardware volume */
-#define ACPI_GPIO      ( 1 << 7)
-#define ACPI_ASSP      ( 1 << 6)
-#define ACPI_SB                ( 1 << 5) /* sb emul */
-#define ACPI_FM                ( 1 << 4) /* fm emul */
-#define ACPI_RB                ( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI      ( 1 << 2) 
-#define ACPI_GP                ( 1 << 1) /* game port */
-#define ACPI_WP                ( 1 << 0) /* wave processor */
-
-#define ACPI_ALL       (0xffff)
-#define ACPI_SLEEP     (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
-                       ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE      (ACPI__10)
-
-/* these masks indicate which units we care about at
-       which states */
-static u16 acpi_state_mask[] = {
-       [ACPI_D0] = ACPI_ALL,
-       [ACPI_D1] = ACPI_SLEEP,
-       [ACPI_D2] = ACPI_SLEEP,
-       [ACPI_D3] = ACPI_NONE
-};
-
-static char version[] __devinitdata =
-KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n";
-
-
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum card_types_t {
-       TYPE_MAESTRO,
-       TYPE_MAESTRO2,
-       TYPE_MAESTRO2E
-};
-
-static const char *card_names[]={
-       [TYPE_MAESTRO] = "ESS Maestro",
-       [TYPE_MAESTRO2] = "ESS Maestro 2",
-       [TYPE_MAESTRO2E] = "ESS Maestro 2E"
-};
-
-static int clock_freq[]={
-       [TYPE_MAESTRO] = (49152000L / 1024L),
-       [TYPE_MAESTRO2] = (50000000L / 1024L),
-       [TYPE_MAESTRO2E] = (50000000L / 1024L)
-};
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-
-static struct notifier_block maestro_nb = {maestro_notifier, NULL, 0};
-
-/* --------------------------------------------------------------------- */
-
-struct ess_state {
-       unsigned int magic;
-       /* FIXME: we probably want submixers in here, but only one record pair */
-       u8 apu[6];              /* l/r output, l/r intput converters, l/r input apus */
-       u8 apu_mode[6];         /* Running mode for this APU */
-       u8 apu_pan[6];          /* Panning setup for this APU */
-       u32 apu_base[6];        /* base address for this apu */
-       struct ess_card *card;  /* Card info */
-       /* wave stuff */
-       unsigned int rateadc, ratedac;
-       unsigned char fmt, enable;
-
-       int index;
-
-       /* this locks around the oss state in the driver */
-       spinlock_t lock;
-       /* only let 1 be opening at a time */
-       struct mutex open_mutex;
-       wait_queue_head_t open_wait;
-       mode_t open_mode;
-
-       /* soundcore stuff */
-       int dev_audio;
-
-       struct dmabuf {
-               void *rawbuf;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               /* XXX zab - swptr only in here so that it can be referenced by
-                       clear_advance, as far as I can tell :( */
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;       /* our oss buffers are ready to go */
-               unsigned endcleared:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-               u16 base;               /* Offset for ptr */
-       } dma_dac, dma_adc;
-
-       /* pointer to each dsp?s piece of the apu->src buffer page */
-       void *mixbuf;
-
-};
-       
-struct ess_card {
-       unsigned int magic;
-
-       /* We keep maestro cards in a linked list */
-       struct ess_card *next;
-
-       int dev_mixer;
-
-       int card_type;
-
-       /* as most of this is static,
-               perhaps it should be a pointer to a global struct */
-       struct mixer_goo {
-               int modcnt;
-               int supported_mixers;
-               int stereo_mixers;
-               int record_sources;
-               /* the caller must guarantee arg sanity before calling these */
-/*             int (*read_mixer)(struct ess_card *card, int index);*/
-               void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right);
-               int (*recmask_io)(struct ess_card *card,int rw,int mask);
-               unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-       } mix;
-       
-       int power_regs;
-               
-       int in_suspend;
-       wait_queue_head_t suspend_queue;
-
-       struct ess_state channels[MAX_DSPS];
-       u16 maestro_map[NR_IDRS];       /* Register map */
-       /* we have to store this junk so that we can come back from a
-               suspend */
-       u16 apu_map[NR_APUS][NR_APU_REGS];      /* contents of apu regs */
-
-       /* this locks around the physical registers on the card */
-       spinlock_t lock;
-
-       /* memory for this card.. wavecache limited :(*/
-       void *dmapages;
-       int dmaorder;
-
-       /* hardware resources */
-       struct pci_dev *pcidev;
-       u32 iobase;
-       u32 irq;
-
-       int bob_freq;
-       char dsps_open;
-
-       int dock_mute_vol;
-};
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val );
-
-static unsigned 
-ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static void check_suspend(struct ess_card *card);
-
-/* --------------------------------------------------------------------- */
-
-
-/*
- *     ESS Maestro AC97 codec programming interface.
- */
-        
-static void maestro_ac97_set(struct ess_card *card, u8 cmd, u16 val)
-{
-       int io = card->iobase;
-       int i;
-       /*
-        *      Wait for the codec bus to be free 
-        */
-
-       check_suspend(card);
-        
-       for(i=0;i<10000;i++)
-       {
-               if(!(inb(io+ESS_AC97_INDEX)&1)) 
-                       break;
-       }
-       /*
-        *      Write the bus
-        */ 
-       outw(val, io+ESS_AC97_DATA);
-       mdelay(1);
-       outb(cmd, io+ESS_AC97_INDEX);
-       mdelay(1);
-}
-
-static u16 maestro_ac97_get(struct ess_card *card, u8 cmd)
-{
-       int io = card->iobase;
-       int sanity=10000;
-       u16 data;
-       int i;
-       
-       check_suspend(card);
-       /*
-        *      Wait for the codec bus to be free 
-        */
-        
-       for(i=0;i<10000;i++)
-       {
-               if(!(inb(io+ESS_AC97_INDEX)&1))
-                       break;
-       }
-
-       outb(cmd|0x80, io+ESS_AC97_INDEX);
-       mdelay(1);
-       
-       while(inb(io+ESS_AC97_INDEX)&1)
-       {
-               sanity--;
-               if(!sanity)
-               {
-                       printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd);
-                       return 0;
-               }
-       }
-       data=inw(io+ESS_AC97_DATA);
-       mdelay(1);
-       return data;
-}
-
-/* OSS interface to the ac97s.. */
-
-#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\
-       SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\
-       SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN)
-
-#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
-       SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\
-       SOUND_MASK_SPEAKER)
-
-#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
-       SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\
-       SOUND_MASK_PHONEIN)
-
-#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) )
-
-/* this table has default mixer values for all OSS mixers.
-       be sure to fill it in if you add oss mixers
-       to anyone's supported mixer defines */
-
-static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_VOLUME] =          0x3232,
-       [SOUND_MIXER_BASS] =            0x3232,
-       [SOUND_MIXER_TREBLE] =          0x3232,
-       [SOUND_MIXER_SPEAKER] =         0x3232,
-       [SOUND_MIXER_MIC] =     0x8000, /* annoying */
-       [SOUND_MIXER_LINE] =    0x3232,
-       [SOUND_MIXER_CD] =      0x3232,
-       [SOUND_MIXER_VIDEO] =   0x3232,
-       [SOUND_MIXER_LINE1] =   0x3232,
-       [SOUND_MIXER_PCM] =             0x3232,
-       [SOUND_MIXER_IGAIN] =           0x3232
-};
-       
-static struct ac97_mixer_hw {
-       unsigned char offset;
-       int scale;
-} ac97_hw[SOUND_MIXER_NRDEVICES]= {
-       [SOUND_MIXER_VOLUME]    =       {0x02,63},
-       [SOUND_MIXER_BASS]      =       {0x08,15},
-       [SOUND_MIXER_TREBLE]    =       {0x08,15},
-       [SOUND_MIXER_SPEAKER]   =       {0x0a,15},
-       [SOUND_MIXER_MIC]       =       {0x0e,31},
-       [SOUND_MIXER_LINE]      =       {0x10,31},
-       [SOUND_MIXER_CD]        =       {0x12,31},
-       [SOUND_MIXER_VIDEO]     =       {0x14,31},
-       [SOUND_MIXER_LINE1]     =       {0x16,31},
-       [SOUND_MIXER_PCM]       =       {0x18,31},
-       [SOUND_MIXER_IGAIN]     =       {0x1c,15}
-};
-
-#if 0 /* *shrug* removed simply because we never used it.
-               feel free to implement again if needed */
-
-/* reads the given OSS mixer from the ac97
-       the caller must have insured that the ac97 knows
-       about that given mixer, and should be holding a
-       spinlock for the card */
-static int ac97_read_mixer(struct ess_card *card, int mixer) 
-{
-       u16 val;
-       int ret=0;
-       struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-       val = maestro_ac97_get(card, mh->offset);
-
-       if(AC97_STEREO_MASK & (1<<mixer)) {
-               /* nice stereo mixers .. */
-               int left,right;
-
-               left = (val >> 8)  & 0x7f;
-               right = val  & 0x7f;
-
-               if (mixer == SOUND_MIXER_IGAIN) {
-                       right = (right * 100) / mh->scale;
-                       left = (left * 100) / mh->scale;
-               } else {
-                       right = 100 - ((right * 100) / mh->scale);
-                       left = 100 - ((left * 100) / mh->scale);
-               }
-
-               ret = left | (right << 8);
-       } else if (mixer == SOUND_MIXER_SPEAKER) {
-               ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
-       } else if (mixer == SOUND_MIXER_MIC) {
-               ret = 100 - (((val & 0x1f) * 100) / mh->scale);
-       /*  the low bit is optional in the tone sliders and masking
-               it lets is avoid the 0xf 'bypass'.. */
-       } else if (mixer == SOUND_MIXER_BASS) {
-               ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
-       } else if (mixer == SOUND_MIXER_TREBLE) {
-               ret = 100 - (((val & 0xe) * 100) / mh->scale);
-       }
-
-       M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret);
-
-       return ret;
-}
-#endif
-
-/* write the OSS encoded volume to the given OSS encoded mixer,
-       again caller's job to make sure all is well in arg land,
-       call with spinlock held */
-       
-/* linear scale -> log */
-static unsigned char lin2log[101] = 
-{
-0, 0 , 15 , 23 , 30 , 34 , 38 , 42 , 45 , 47 ,
-50 , 52 , 53 , 55 , 57 , 58 , 60 , 61 , 62 ,
-63 , 65 , 66 , 67 , 68 , 69 , 69 , 70 , 71 ,
-72 , 73 , 73 , 74 , 75 , 75 , 76 , 77 , 77 ,
-78 , 78 , 79 , 80 , 80 , 81 , 81 , 82 , 82 ,
-83 , 83 , 84 , 84 , 84 , 85 , 85 , 86 , 86 ,
-87 , 87 , 87 , 88 , 88 , 88 , 89 , 89 , 89 ,
-90 , 90 , 90 , 91 , 91 , 91 , 92 , 92 , 92 ,
-93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 ,
-95 , 95 , 96 , 96 , 96 , 96 , 97 , 97 , 97 ,
-97 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 
-};
-
-static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right)
-{
-       u16 val=0;
-       struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-       M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right);
-
-       if(AC97_STEREO_MASK & (1<<mixer)) {
-               /* stereo mixers, mute them if we can */
-
-               if (mixer == SOUND_MIXER_IGAIN) {
-                       /* igain's slider is reversed.. */
-                       right = (right * mh->scale) / 100;
-                       left = (left * mh->scale) / 100;
-                       if ((left == 0) && (right == 0))
-                               val |= 0x8000;
-               } else if (mixer == SOUND_MIXER_PCM || mixer == SOUND_MIXER_CD) {
-                       /* log conversion seems bad for them */
-                       if ((left == 0) && (right == 0))
-                               val = 0x8000;
-                       right = ((100 - right) * mh->scale) / 100;
-                       left = ((100 - left) * mh->scale) / 100;
-               } else {
-                       /* log conversion for the stereo controls */
-                       if((left == 0) && (right == 0))
-                               val = 0x8000;
-                       right = ((100 - lin2log[right]) * mh->scale) / 100;
-                       left = ((100 - lin2log[left]) * mh->scale) / 100;
-               }
-
-               val |= (left << 8) | right;
-
-       } else if (mixer == SOUND_MIXER_SPEAKER) {
-               val = (((100 - left) * mh->scale) / 100) << 1;
-       } else if (mixer == SOUND_MIXER_MIC) {
-               val = maestro_ac97_get(card, mh->offset) & ~0x801f;
-               val |= (((100 - left) * mh->scale) / 100);
-       /*  the low bit is optional in the tone sliders and masking
-               it lets is avoid the 0xf 'bypass'.. */
-       } else if (mixer == SOUND_MIXER_BASS) {
-               val = maestro_ac97_get(card , mh->offset) & ~0x0f00;
-               val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
-       } else if (mixer == SOUND_MIXER_TREBLE)  {
-               val = maestro_ac97_get(card , mh->offset) & ~0x000f;
-               val |= (((100 - left) * mh->scale) / 100) & 0x000e;
-       }
-
-       maestro_ac97_set(card , mh->offset, val);
-       
-       M_printk(" -> %x\n",val);
-}
-
-/* the following tables allow us to go from 
-       OSS <-> ac97 quickly. */
-
-enum ac97_recsettings {
-       AC97_REC_MIC=0,
-       AC97_REC_CD,
-       AC97_REC_VIDEO,
-       AC97_REC_AUX,
-       AC97_REC_LINE,
-       AC97_REC_STEREO, /* combination of all enabled outputs..  */
-       AC97_REC_MONO,        /*.. or the mono equivalent */
-       AC97_REC_PHONE        
-};
-
-static unsigned int ac97_oss_mask[] = {
-       [AC97_REC_MIC] = SOUND_MASK_MIC, 
-       [AC97_REC_CD] = SOUND_MASK_CD, 
-       [AC97_REC_VIDEO] = SOUND_MASK_VIDEO, 
-       [AC97_REC_AUX] = SOUND_MASK_LINE1, 
-       [AC97_REC_LINE] = SOUND_MASK_LINE, 
-       [AC97_REC_PHONE] = SOUND_MASK_PHONEIN
-};
-
-/* indexed by bit position */
-static unsigned int ac97_oss_rm[] = {
-       [SOUND_MIXER_MIC] = AC97_REC_MIC,
-       [SOUND_MIXER_CD] = AC97_REC_CD,
-       [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
-       [SOUND_MIXER_LINE1] = AC97_REC_AUX,
-       [SOUND_MIXER_LINE] = AC97_REC_LINE,
-       [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
-};
-       
-/* read or write the recmask 
-       the ac97 can really have left and right recording
-       inputs independently set, but OSS doesn't seem to 
-       want us to express that to the user. 
-       the caller guarantees that we have a supported bit set,
-       and they must be holding the card's spinlock */
-static int 
-ac97_recmask_io(struct ess_card *card, int read, int mask) 
-{
-       unsigned int val = ac97_oss_mask[ maestro_ac97_get(card, 0x1a) & 0x7 ];
-
-       if (read) return val;
-
-       /* oss can have many inputs, maestro can't.  try
-               to pick the 'new' one */
-
-       if (mask != val) mask &= ~val;
-
-       val = ffs(mask) - 1; 
-       val = ac97_oss_rm[val];
-       val |= val << 8;  /* set both channels */
-
-       M_printk("maestro: setting ac97 recmask to 0x%x\n",val);
-
-       maestro_ac97_set(card,0x1a,val);
-
-       return 0;
-};
-
-/*
- *     The Maestro can be wired to a standard AC97 compliant codec
- *     (see www.intel.com for the pdf's on this), or to a PT101 codec
- *     which appears to be the ES1918 (data sheet on the esstech.com.tw site)
- *
- *     The PT101 setup is untested.
- */
-static u16 __init maestro_ac97_init(struct ess_card *card)
-{
-       u16 vend1, vend2, caps;
-
-       card->mix.supported_mixers = AC97_SUPPORTED_MASK;
-       card->mix.stereo_mixers = AC97_STEREO_MASK;
-       card->mix.record_sources = AC97_RECORD_MASK;
-/*     card->mix.read_mixer = ac97_read_mixer;*/
-       card->mix.write_mixer = ac97_write_mixer;
-       card->mix.recmask_io = ac97_recmask_io;
-
-       vend1 = maestro_ac97_get(card, 0x7c);
-       vend2 = maestro_ac97_get(card, 0x7e);
-
-       caps = maestro_ac97_get(card, 0x00);
-
-       printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n",
-               vend1,vend2,caps,maestro_ac97_get(card,0x26) & 0xf);
-
-       if (! (caps & 0x4) ) {
-               /* no bass/treble nobs */
-               card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
-       }
-
-       /* XXX endianness, dork head. */
-       /* vendor specifc bits.. */
-       switch ((long)(vend1 << 16) | vend2) {
-       case 0x545200ff:        /* TriTech */
-               /* no idea what this does */
-               maestro_ac97_set(card,0x2a,0x0001);
-               maestro_ac97_set(card,0x2c,0x0000);
-               maestro_ac97_set(card,0x2c,0xffff);
-               break;
-#if 0  /* i thought the problems I was seeing were with
-       the 1921, but apparently they were with the pci board
-       it was on, so this code is commented out.
-        lets see if this holds true. */
-       case 0x83847609:        /* ESS 1921 */
-               /* writing to 0xe (mic) or 0x1a (recmask) seems
-                       to hang this codec */
-               card->mix.supported_mixers &= ~(SOUND_MASK_MIC);
-               card->mix.record_sources = 0;
-               card->mix.recmask_io = NULL;
-#if 0  /* don't ask.  I have yet to see what these actually do. */
-               maestro_ac97_set(card,0x76,0xABBA); /* o/~ Take a chance on me o/~ */
-               udelay(20);
-               maestro_ac97_set(card,0x78,0x3002);
-               udelay(20);
-               maestro_ac97_set(card,0x78,0x3802);
-               udelay(20);
-#endif
-               break;
-#endif
-       default: break;
-       }
-
-       maestro_ac97_set(card, 0x1E, 0x0404);
-       /* null misc stuff */
-       maestro_ac97_set(card, 0x20, 0x0000);
-
-       return 0;
-}
-
-#if 0  /* there has been 1 person on the planet with a pt101 that we
-       know of.  If they care, they can put this back in :) */
-static u16 maestro_pt101_init(struct ess_card *card,int iobase)
-{
-       printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
-       /* who knows.. */
-       maestro_ac97_set(iobase, 0x2A, 0x0001);
-       maestro_ac97_set(iobase, 0x2C, 0x0000);
-       maestro_ac97_set(iobase, 0x2C, 0xFFFF);
-       maestro_ac97_set(iobase, 0x10, 0x9F1F);
-       maestro_ac97_set(iobase, 0x12, 0x0808);
-       maestro_ac97_set(iobase, 0x14, 0x9F1F);
-       maestro_ac97_set(iobase, 0x16, 0x9F1F);
-       maestro_ac97_set(iobase, 0x18, 0x0404);
-       maestro_ac97_set(iobase, 0x1A, 0x0000);
-       maestro_ac97_set(iobase, 0x1C, 0x0000);
-       maestro_ac97_set(iobase, 0x02, 0x0404);
-       maestro_ac97_set(iobase, 0x04, 0x0808);
-       maestro_ac97_set(iobase, 0x0C, 0x801F);
-       maestro_ac97_set(iobase, 0x0E, 0x801F);
-       return 0;
-}
-#endif
-
-/* this is very magic, and very slow.. */
-static void 
-maestro_ac97_reset(int ioaddr, struct pci_dev *pcidev)
-{
-       u16 save_68;
-       u16 w;
-       u32 vend;
-
-       outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-       outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-       outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-       /* reset the first codec */
-       outw(0x0000,  ioaddr+0x36);
-       save_68 = inw(ioaddr+0x68);
-       pci_read_config_word(pcidev, 0x58, &w); /* something magical with gpio and bus arb. */
-       pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &vend);
-       if( w & 0x1)
-               save_68 |= 0x10;
-       outw(0xfffe, ioaddr + 0x64);    /* tickly gpio 0.. */
-       outw(0x0001, ioaddr + 0x68);
-       outw(0x0000, ioaddr + 0x60);
-       udelay(20);
-       outw(0x0001, ioaddr + 0x60);
-       mdelay(20);
-
-       outw(save_68 | 0x1, ioaddr + 0x68);     /* now restore .. */
-       outw( (inw(ioaddr + 0x38) & 0xfffc)|0x1, ioaddr + 0x38);
-       outw( (inw(ioaddr + 0x3a) & 0xfffc)|0x1, ioaddr + 0x3a);
-       outw( (inw(ioaddr + 0x3c) & 0xfffc)|0x1, ioaddr + 0x3c);
-
-       /* now the second codec */
-       outw(0x0000,  ioaddr+0x36);
-       outw(0xfff7, ioaddr + 0x64);
-       save_68 = inw(ioaddr+0x68);
-       outw(0x0009, ioaddr + 0x68);
-       outw(0x0001, ioaddr + 0x60);
-       udelay(20);
-       outw(0x0009, ioaddr + 0x60);
-       mdelay(500);    /* .. ouch.. */
-       outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-       outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-       outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-#if 0 /* the loop here needs to be much better if we want it.. */
-       M_printk("trying software reset\n");
-       /* try and do a software reset */
-       outb(0x80|0x7c, ioaddr + 0x30);
-       for (w=0; ; w++) {
-               if ((inw(ioaddr+ 0x30) & 1) == 0) {
-                       if(inb(ioaddr + 0x32) !=0) break;
-
-                       outb(0x80|0x7d, ioaddr + 0x30);
-                       if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-                       outb(0x80|0x7f, ioaddr + 0x30);
-                       if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-               }
-
-               if( w > 10000) {
-                       outb( inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);  /* do a software reset */
-                       mdelay(500); /* oh my.. */
-                       outb( inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37);  
-                       udelay(1);
-                       outw( 0x80, ioaddr+0x30);
-                       for(w = 0 ; w < 10000; w++) {
-                               if((inw(ioaddr + 0x30) & 1) ==0) break;
-                       }
-               }
-       }
-#endif
-       if ( vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
-               /* turn on external amp? */
-               outw(0xf9ff, ioaddr + 0x64);
-               outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68);
-               outw(0x0209, ioaddr + 0x60);
-       }
-
-       /* Turn on the 978 docking chip.
-          First frob the "master output enable" bit,
-          then set most of the playback volume control registers to max. */
-       outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
-       outb(0xff, ioaddr+0xc3);
-       outb(0xff, ioaddr+0xc4);
-       outb(0xff, ioaddr+0xc6);
-       outb(0xff, ioaddr+0xc8);
-       outb(0x3f, ioaddr+0xcf);
-       outb(0x3f, ioaddr+0xd0);
-}
-/*
- *     Indirect register access. Not all registers are readable so we
- *     need to keep register state ourselves
- */
-#define WRITEABLE_MAP  0xEFFFFF
-#define READABLE_MAP   0x64003F
-
-/*
- *     The Maestro engineers were a little indirection happy. These indirected
- *     registers themselves include indirect registers at another layer
- */
-
-static void __maestro_write(struct ess_card *card, u16 reg, u16 data)
-{
-       long ioaddr = card->iobase;
-
-       outw(reg, ioaddr+0x02);
-       outw(data, ioaddr+0x00);
-       if( reg >= NR_IDRS) printk("maestro: IDR %d out of bounds!\n",reg);
-       else card->maestro_map[reg]=data;
-
-}
-static void maestro_write(struct ess_state *s, u16 reg, u16 data)
-{
-       unsigned long flags;
-
-       check_suspend(s->card);
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       __maestro_write(s->card,reg,data);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 __maestro_read(struct ess_card *card, u16 reg)
-{
-       long ioaddr = card->iobase;
-
-       outw(reg, ioaddr+0x02);
-       return card->maestro_map[reg]=inw(ioaddr+0x00);
-}
-
-static u16 maestro_read(struct ess_state *s, u16 reg)
-{
-       if(READABLE_MAP & (1<<reg))
-       {
-               unsigned long flags;
-               check_suspend(s->card);
-               spin_lock_irqsave(&s->card->lock,flags);
-
-               __maestro_read(s->card,reg);
-
-               spin_unlock_irqrestore(&s->card->lock,flags);
-       }
-       return s->card->maestro_map[reg];
-}
-
-/*
- *     These routines handle accessing the second level indirections to the
- *     wave ram.
- */
-
-/*
- *     The register names are the ones ESS uses (see 104T31.ZIP)
- */
-#define IDR0_DATA_PORT         0x00
-#define IDR1_CRAM_POINTER      0x01
-#define IDR2_CRAM_DATA         0x02
-#define IDR3_WAVE_DATA         0x03
-#define IDR4_WAVE_PTR_LOW      0x04
-#define IDR5_WAVE_PTR_HI       0x05
-#define IDR6_TIMER_CTRL                0x06
-#define IDR7_WAVE_ROMRAM       0x07
-
-static void apu_index_set(struct ess_card *card, u16 index)
-{
-       int i;
-       __maestro_write(card, IDR1_CRAM_POINTER, index);
-       for(i=0;i<1000;i++)
-               if(__maestro_read(card, IDR1_CRAM_POINTER)==index)
-                       return;
-       printk(KERN_WARNING "maestro: APU register select failed.\n");
-}
-
-static void apu_data_set(struct ess_card *card, u16 data)
-{
-       int i;
-       for(i=0;i<1000;i++)
-       {
-               if(__maestro_read(card, IDR0_DATA_PORT)==data)
-                       return;
-               __maestro_write(card, IDR0_DATA_PORT, data);
-       }
-}
-
-/*
- *     This is the public interface for APU manipulation. It handles the
- *     interlock to avoid two APU writes in parallel etc. Don't diddle
- *     directly with the stuff above.
- */
-
-static void apu_set_register(struct ess_state *s, u16 channel, u8 reg, u16 data)
-{
-       unsigned long flags;
-       
-       check_suspend(s->card);
-
-       if(channel&ESS_CHAN_HARD)
-               channel&=~ESS_CHAN_HARD;
-       else
-       {
-               if(channel>5)
-                       printk("BAD CHANNEL %d.\n",channel);
-               else
-                       channel = s->apu[channel];
-               /* store based on real hardware apu/reg */
-               s->card->apu_map[channel][reg]=data;
-       }
-       reg|=(channel<<4);
-       
-       /* hooray for double indirection!! */
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       apu_index_set(s->card, reg);
-       apu_data_set(s->card, data);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 apu_get_register(struct ess_state *s, u16 channel, u8 reg)
-{
-       unsigned long flags;
-       u16 v;
-       
-       check_suspend(s->card);
-
-       if(channel&ESS_CHAN_HARD)
-               channel&=~ESS_CHAN_HARD;
-       else
-               channel = s->apu[channel];
-
-       reg|=(channel<<4);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       apu_index_set(s->card, reg);
-       v=__maestro_read(s->card, IDR0_DATA_PORT);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-       return v;
-}
-
-
-/*
- *     The wavecache buffers between the APUs and
- *     pci bus mastering
- */
-static void wave_set_register(struct ess_state *s, u16 reg, u16 value)
-{
-       long ioaddr = s->card->iobase;
-       unsigned long flags;
-       check_suspend(s->card);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       outw(reg, ioaddr+0x10);
-       outw(value, ioaddr+0x12);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 wave_get_register(struct ess_state *s, u16 reg)
-{
-       long ioaddr = s->card->iobase;
-       unsigned long flags;
-       u16 value;
-       check_suspend(s->card);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-       outw(reg, ioaddr+0x10);
-       value=inw(ioaddr+0x12);
-       spin_unlock_irqrestore(&s->card->lock,flags);
-       
-       return value;
-}
-
-static void sound_reset(int ioaddr)
-{
-       outw(0x2000, 0x18+ioaddr);
-       udelay(1);
-       outw(0x0000, 0x18+ioaddr);
-       udelay(1);
-}
-
-/* sets the play formats of these apus, should be passed the already shifted format */
-static void set_apu_fmt(struct ess_state *s, int apu, int mode)
-{
-       int apu_fmt = 0x10;
-
-       if(!(mode&ESS_FMT_16BIT)) apu_fmt+=0x20; 
-       if((mode&ESS_FMT_STEREO)) apu_fmt+=0x10; 
-       s->apu_mode[apu]   = apu_fmt;
-       s->apu_mode[apu+1] = apu_fmt;
-}
-
-/* this only fixes the output apu mode to be later set by start_dac and
-       company.  output apu modes are set in ess_rec_setup */
-static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data)
-{
-       s->fmt = (s->fmt & mask) | data;
-       set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK);
-}
-
-/* this is off by a little bit.. */
-static u32 compute_rate(struct ess_state *s, u32 freq)
-{
-       u32 clock = clock_freq[s->card->card_type];     
-
-       freq = (freq * clocking)/48000;
-       
-       if (freq == 48000) 
-               return 0x10000;
-
-       return ((freq / clock) <<16 )+  
-               (((freq % clock) << 16) / clock);
-}
-
-static void set_dac_rate(struct ess_state *s, unsigned int rate)
-{
-       u32 freq;
-       int fmt = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-
-       s->ratedac = rate;
-
-       if(! (fmt & ESS_FMT_16BIT) && !(fmt & ESS_FMT_STEREO))
-               rate >>= 1;
-
-/*     M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/
-
-       freq = compute_rate(s, rate);
-       
-       /* Load the frequency, turn on 6dB */
-       apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 0, 3, freq>>8);
-       apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 1, 3, freq>>8);
-}
-
-static void set_adc_rate(struct ess_state *s, unsigned rate)
-{
-       u32 freq;
-
-       /* Sample Rate conversion APUs don't like 0x10000 for their rate */
-       if (rate > 47999)
-               rate = 47999;
-       if (rate < 4000)
-               rate = 4000;
-
-       s->rateadc = rate;
-
-       freq = compute_rate(s, rate);
-       
-       /* Load the frequency, turn on 6dB */
-       apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 2, 3, freq>>8);
-       apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 3, 3, freq>>8);
-
-       /* fix mixer rate at 48khz.  and its _must_ be 0x10000. */
-       freq = 0x10000;
-
-       apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 4, 3, freq>>8);
-       apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 5, 3, freq>>8);
-}
-
-/* Stop our host of recording apus */
-static inline void stop_adc(struct ess_state *s)
-{
-       /* XXX lets hope we don't have to lock around this */
-       if (! (s->enable & ADC_RUNNING)) return;
-
-       s->enable &= ~ADC_RUNNING;
-       apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F);
-       apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F);
-       apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F);
-       apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F);
-}      
-
-/* stop output apus */
-static void stop_dac(struct ess_state *s)
-{
-       /* XXX have to lock around this? */
-       if (! (s->enable & DAC_RUNNING)) return;
-
-       s->enable &= ~DAC_RUNNING;
-       apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F);
-       apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F);
-}      
-
-static void start_dac(struct ess_state *s)
-{
-       /* XXX locks? */
-       if (    (s->dma_dac.mapped || s->dma_dac.count > 0) && 
-               s->dma_dac.ready &&
-               (! (s->enable & DAC_RUNNING)) ) {
-
-               s->enable |= DAC_RUNNING;
-
-               apu_set_register(s, 0, 0, 
-                       (apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]);
-
-               if((s->fmt >> ESS_DAC_SHIFT)  & ESS_FMT_STEREO) 
-                       apu_set_register(s, 1, 0, 
-                               (apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]);
-       }
-}      
-
-static void start_adc(struct ess_state *s)
-{
-       /* XXX locks? */
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-           && s->dma_adc.ready && (! (s->enable & ADC_RUNNING)) ) {
-
-               s->enable |= ADC_RUNNING;
-               apu_set_register(s, 2, 0, 
-                       (apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]);
-               apu_set_register(s, 4, 0, 
-                       (apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]);
-
-               if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       apu_set_register(s, 3, 0, 
-                               (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]);
-                       apu_set_register(s, 5, 0, 
-                               (apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]);
-               }
-                       
-       }
-}      
-
-
-/*
- *     Native play back driver 
- */
-
-/* the mode passed should be already shifted and masked */
-static void 
-ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-       u32 pa;
-       u32 tmpval;
-       int high_apu = 0;
-       int channel;
-
-       M_printk("mode=%d rate=%d buf=%p len=%d.\n",
-               mode, rate, buffer, size);
-               
-       /* all maestro sizes are in 16bit words */
-       size >>=1;
-
-       if(mode&ESS_FMT_STEREO) {
-               high_apu++;
-               /* only 16/stereo gets size divided */
-               if(mode&ESS_FMT_16BIT)
-                       size>>=1;
-       }
-       
-       for(channel=0; channel <= high_apu; channel++)
-       {
-               pa = virt_to_bus(buffer);
-
-               /* set the wavecache control reg */
-               tmpval = (pa - 0x10) & 0xFFF8;
-               if(!(mode & ESS_FMT_16BIT)) tmpval |= 4;
-               if(mode & ESS_FMT_STEREO) tmpval |= 2;
-               ess->apu_base[channel]=tmpval;
-               wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-               
-               pa -= virt_to_bus(ess->card->dmapages);
-               pa>>=1; /* words */
-               
-               /* base offset of dma calcs when reading the pointer
-                       on the left one */
-               if(!channel) ess->dma_dac.base = pa&0xFFFF;
-               
-               pa|=0x00400000;                 /* System RAM */
-
-               /* XXX the 16bit here might not be needed.. */
-               if((mode & ESS_FMT_STEREO) && (mode & ESS_FMT_16BIT)) {
-                       if(channel) 
-                               pa|=0x00800000;                 /* Stereo */
-                       pa>>=1;
-               }
-                       
-/* XXX think about endianess when writing these registers */
-               M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa);
-               /* start of sample */
-               apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-               apu_set_register(ess, channel, 5, pa&0xFFFF);
-               /* sample end */
-               apu_set_register(ess, channel, 6, (pa+size)&0xFFFF);
-               /* setting loop len == sample len */
-               apu_set_register(ess, channel, 7, size);
-               
-               /* clear effects/env.. */
-               apu_set_register(ess, channel, 8, 0x0000);
-               /* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
-               apu_set_register(ess, channel, 9, 0xD000);
-
-               /* clear routing stuff */
-               apu_set_register(ess, channel, 11, 0x0000);
-               /* dma on, no envelopes, filter to all 1s) */
-               apu_set_register(ess, channel, 0, 0x400F);
-               
-               if(mode&ESS_FMT_16BIT)
-                       ess->apu_mode[channel]=0x10;
-               else
-                       ess->apu_mode[channel]=0x30;
-
-               if(mode&ESS_FMT_STEREO) {
-                       /* set panning: left or right */
-                       apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0 : 0x10));
-                       ess->apu_mode[channel] += 0x10;
-               } else
-                       apu_set_register(ess, channel, 10, 0x8F08);
-       }
-       
-       /* clear WP interrupts */
-       outw(1, ess->card->iobase+0x04);
-       /* enable WP ints */
-       outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-       /* go team! */
-       set_dac_rate(ess,rate);
-       start_dac(ess);
-}
-
-/*
- *     Native record driver 
- */
-
-/* again, passed mode is alrady shifted/masked */
-static void 
-ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-       int apu_step = 2;
-       int channel;
-
-       M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n",
-               mode, rate, buffer, size);
-               
-       /* all maestro sizes are in 16bit words */
-       size >>=1;
-
-       /* we're given the full size of the buffer, but
-       in stereo each channel will only use its half */
-       if(mode&ESS_FMT_STEREO) {
-               size >>=1; 
-               apu_step = 1;
-       }
-       
-       /* APU assignments: 2 = mono/left SRC
-                           3 = right SRC
-                           4 = mono/left Input Mixer
-                           5 = right Input Mixer */
-       for(channel=2;channel<6;channel+=apu_step)
-       {
-               int i;
-               int bsize, route;
-               u32 pa;
-               u32 tmpval;
-
-               /* data seems to flow from the codec, through an apu into
-                       the 'mixbuf' bit of page, then through the SRC apu
-                       and out to the real 'buffer'.  ok.  sure.  */
-               
-               if(channel & 0x04) {
-                       /* ok, we're an input mixer going from adc
-                               through the mixbuf to the other apus */
-
-                       if(!(channel & 0x01)) { 
-                               pa = virt_to_bus(ess->mixbuf);
-                       } else {
-                               pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4));
-                       }
-
-                       /* we source from a 'magic' apu */
-                       bsize = PAGE_SIZE >> 5; /* half of this channels alloc, in words */
-                       route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */
-                       ess->apu_mode[channel] = 0x90;  /* Input Mixer */
-
-               } else {  
-                       /* we're a rate converter taking
-                               input from the input apus and outputing it to
-                               system memory */
-                       if(!(channel & 0x01))  {
-                               pa = virt_to_bus(buffer);
-                       } else {
-                               /* right channel records its split half.
-                               *2 accommodates for rampant shifting earlier */
-                               pa = virt_to_bus(buffer + size*2);
-                       }
-
-                       ess->apu_mode[channel] = 0xB0;  /* Sample Rate Converter */
-
-                       bsize = size; 
-                       /* get input from inputing apu */
-                       route = channel + 2;
-               }
-
-               M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel);
-               
-               /* set the wavecache control reg */
-               tmpval = (pa - 0x10) & 0xFFF8;
-               ess->apu_base[channel]=tmpval;
-               wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-               
-               pa -= virt_to_bus(ess->card->dmapages);
-               pa>>=1; /* words */
-               
-               /* base offset of dma calcs when reading the pointer
-                       on this left one */
-               if(channel==2) ess->dma_adc.base = pa&0xFFFF;
-
-               pa|=0x00400000;                 /* bit 22 -> System RAM */
-
-               M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", 
-                       ess->apu[channel], pa, bsize, route);
-               
-               /* Begin loading the APU */             
-               for(i=0;i<15;i++)               /* clear all PBRs */
-                       apu_set_register(ess, channel, i, 0x0000);
-                       
-               apu_set_register(ess, channel, 0, 0x400F);
-
-               /* need to enable subgroups.. and we should probably
-                       have different groups for different /dev/dsps..  */
-               apu_set_register(ess, channel, 2, 0x8);
-                               
-               /* Load the buffer into the wave engine */
-               apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-               /* XXX reg is little endian.. */
-               apu_set_register(ess, channel, 5, pa&0xFFFF);
-               apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF);
-               apu_set_register(ess, channel, 7, bsize);
-                               
-               /* clear effects/env.. */
-               apu_set_register(ess, channel, 8, 0x00F0);
-               
-               /* amplitude now?  sure.  why not.  */
-               apu_set_register(ess, channel, 9, 0x0000);
-
-               /* set filter tune, radius, polar pan */
-               apu_set_register(ess, channel, 10, 0x8F08);
-
-               /* route input */
-               apu_set_register(ess, channel, 11, route);
-       }
-       
-       /* clear WP interrupts */
-       outw(1, ess->card->iobase+0x04);
-       /* enable WP ints */
-       outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-       /* let 'er rip */
-       set_adc_rate(ess,rate);
-       start_adc(ess);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-       M_printk("set_dmaa??\n");
-}
-
-static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-       M_printk("set_dmac??\n");
-}
-
-/* Playback pointer */
-static inline unsigned get_dmaa(struct ess_state *s)
-{
-       int offset;
-
-       offset = apu_get_register(s,0,5);
-
-/*     M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */
-       
-       offset-=s->dma_dac.base;
-
-       return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/* Record pointer */
-static inline unsigned get_dmac(struct ess_state *s)
-{
-       int offset;
-
-       offset = apu_get_register(s,2,5);
-
-/*     M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */
-       
-       /* The offset is an address not a position relative to base */
-       offset-=s->dma_adc.base;
-       
-       return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/*
- *     Meet Bob, the timer...
- */
-
-static irqreturn_t ess_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static void stop_bob(struct ess_state *s)
-{
-       /* Mask IDR 11,17 */
-       maestro_write(s,  0x11, maestro_read(s, 0x11)&~1);
-       maestro_write(s,  0x17, maestro_read(s, 0x17)&~1);
-}
-
-/* eventually we could be clever and limit bob ints
-       to the frequency at which our smallest duration
-       chunks may expire */
-#define ESS_SYSCLK     50000000
-static void start_bob(struct ess_state *s)
-{
-       int prescale;
-       int divide;
-       
-       /* XXX make freq selector much smarter, see calc_bob_rate */
-       int freq = 200; 
-       
-       /* compute ideal interrupt frequency for buffer size & play rate */
-       /* first, find best prescaler value to match freq */
-       for(prescale=5;prescale<12;prescale++)
-               if(freq > (ESS_SYSCLK>>(prescale+9)))
-                       break;
-                       
-       /* next, back off prescaler whilst getting divider into optimum range */
-       divide=1;
-       while((prescale > 5) && (divide<32))
-       {
-               prescale--;
-               divide <<=1;
-       }
-       divide>>=1;
-       
-       /* now fine-tune the divider for best match */
-       for(;divide<31;divide++)
-               if(freq >= ((ESS_SYSCLK>>(prescale+9))/(divide+1)))
-                       break;
-       
-       /* divide = 0 is illegal, but don't let prescale = 4! */
-       if(divide == 0)
-       {
-               divide++;
-               if(prescale>5)
-                       prescale--;
-       }
-
-       maestro_write(s, 6, 0x9000 | (prescale<<5) | divide); /* set reg */
-       
-       /* Now set IDR 11/17 */
-       maestro_write(s, 0x11, maestro_read(s, 0x11)|1);
-       maestro_write(s, 0x17, maestro_read(s, 0x17)|1);
-}
-/* --------------------------------------------------------------------- */
-
-/* this quickly calculates the frequency needed for bob
-       and sets it if its different than what bob is
-       currently running at.  its called often so 
-       needs to be fairly quick. */
-#define BOB_MIN 50
-#define BOB_MAX 400
-static void calc_bob_rate(struct ess_state *s) {
-#if 0 /* this thing tries to set the frequency of bob such that
-       there are 2 interrupts / buffer walked by the dac/adc.  That
-       is probably very wrong for people who actually care about 
-       mid buffer positioning.  it should be calculated as bytes/interrupt
-       and that needs to be decided :)  so for now just use the static 150
-       in start_bob.*/
-
-       unsigned int dac_rate=2,adc_rate=1,newrate;
-       static int israte=-1;
-
-       if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN;
-       else  {
-               dac_rate =      (2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-                               (s->dma_dac.fragsize) ;
-       }
-               
-       if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN;
-       else {
-               adc_rate =      (2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-                               (s->dma_adc.fragsize) ;
-       }
-
-       if(dac_rate > adc_rate) newrate = adc_rate;
-       else newrate=dac_rate;
-
-       if(newrate > BOB_MAX) newrate = BOB_MAX;
-       else {
-               if(newrate < BOB_MIN) 
-                       newrate = BOB_MIN;
-       }
-
-       if( israte != newrate) {
-               printk("dac: %d  adc: %d rate: %d\n",dac_rate,adc_rate,israte);
-               israte=newrate;
-       }
-#endif
-
-}
-
-static int 
-prog_dmabuf(struct ess_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       unsigned bytepersec;
-       unsigned bufs;
-       unsigned char fmt;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       fmt = s->fmt;
-       if (rec) {
-               stop_adc(s);
-               fmt >>= ESS_ADC_SHIFT;
-       } else {
-               stop_dac(s);
-               fmt >>= ESS_DAC_SHIFT;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       fmt &= ESS_FMT_MASK;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-       /* this algorithm is a little nuts.. where did /1000 come from? */
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3; 
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-
-       M_printk("maestro: setup oss: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-       memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) 
-               ess_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-       else 
-               ess_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->ready = 1;
-
-       return 0;
-}
-
-static __inline__ void 
-clear_advance(struct ess_state *s)
-{
-       unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-       
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-       
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               /* account for wrapping? */
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void 
-ess_update_ptr(struct ess_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-               /* oh boy should this all be re-written.  everything in the current code paths think
-               that the various counters/pointers are expressed in bytes to the user but we have
-               two apus doing stereo stuff so we fix it up here.. it propagates to all the various
-               counters from here.  */
-               if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize;
-               } else {
-                       hwptr = get_dmac(s) % s->dma_adc.dmasize;
-               }
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               /* FILL ME 
-                               wrindir(s, SV_CIENABLE, s->enable); */
-                               stop_adc(s); 
-                               /* brute force everyone back in sync, sigh */
-                               s->dma_adc.count = 0;
-                               s->dma_adc.swptr = 0;
-                               s->dma_adc.hwptr = 0;
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-               /* the apu only reports the length it has seen, not the
-                       length of the memory that has been used (the WP
-                       knows that) */
-               if ( ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK) == (ESS_FMT_STEREO|ESS_FMT_16BIT))
-                       hwptr<<=1;
-
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-/*             M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-                               wake_up(&s->dma_dac.wait);
-                       }
-               } else {
-                       s->dma_dac.count -= diff;
-/*                     M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */
-                       if (s->dma_dac.count <= 0) {
-                               M_printk("underflow! diff: %d count: %d hw: %d sw: %d\n", diff, s->dma_dac.count, 
-                                       hwptr, s->dma_dac.swptr);
-                               /* FILL ME 
-                               wrindir(s, SV_CIENABLE, s->enable); */
-                               /* XXX how on earth can calling this with the lock held work.. */
-                               stop_dac(s);
-                               /* brute force everyone back in sync, sigh */
-                               s->dma_dac.count = 0; 
-                               s->dma_dac.swptr = hwptr; 
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-                               wake_up(&s->dma_dac.wait);
-/*                             printk("waking up DAC count: %d sw: %d hw: %d\n",s->dma_dac.count, s->dma_dac.swptr, 
-                                       hwptr);*/
-                       }
-               }
-       }
-}
-
-static irqreturn_t
-ess_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct ess_state *s;
-        struct ess_card *c = (struct ess_card *)dev_id;
-       int i;
-       u32 event;
-
-       if ( ! (event = inb(c->iobase+0x1A)) )
-               return IRQ_NONE;
-
-       outw(inw(c->iobase+4)&1, c->iobase+4);
-
-/*     M_printk("maestro int: %x\n",event);*/
-       if(event&(1<<6))
-       {
-               int x;
-               enum {UP_EVT, DOWN_EVT, MUTE_EVT} vol_evt;
-               int volume;
-
-               /* Figure out which volume control button was pushed,
-                  based on differences from the default register
-                  values. */
-               x = inb(c->iobase+0x1c);
-               if (x&1) vol_evt = MUTE_EVT;
-               else if (((x>>1)&7) > 4) vol_evt = UP_EVT;
-               else vol_evt = DOWN_EVT;
-
-               /* Reset the volume control registers. */
-               outb(0x88, c->iobase+0x1c);
-               outb(0x88, c->iobase+0x1d);
-               outb(0x88, c->iobase+0x1e);
-               outb(0x88, c->iobase+0x1f);
-
-               /* Deal with the button press in a hammer-handed
-                  manner by adjusting the master mixer volume. */
-               volume = c->mix.mixer_state[0] & 0xff;
-               if (vol_evt == UP_EVT) {
-                       volume += 5;
-                       if (volume > 100)
-                               volume = 100;
-               }
-               else if (vol_evt == DOWN_EVT) {
-                       volume -= 5;
-                       if (volume < 0)
-                               volume = 0;
-               } else {
-                       /* vol_evt == MUTE_EVT */
-                       if (volume == 0)
-                               volume = c->dock_mute_vol;
-                       else {
-                               c->dock_mute_vol = volume;
-                               volume = 0;
-                       }
-               }
-               set_mixer (c, 0, (volume << 8) | volume);
-       }
-
-       /* Ack all the interrupts. */
-       outb(0xFF, c->iobase+0x1A);
-               
-       /*
-        *      Update the pointers for all APU's we are running.
-        */
-       for(i=0;i<NR_DSPS;i++)
-       {
-               s=&c->channels[i];
-               if(s->dev_audio == -1)
-                       break;
-               spin_lock(&s->lock);
-               ess_update_ptr(s);
-               spin_unlock(&s->lock);
-       }
-       return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-       if (!(FOO) || (FOO)->magic != MAG) { \
-               printk(invalid_magic,__FUNCTION__);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC)
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) 
-{
-       unsigned int left,right;
-       /* cleanse input a little */
-       right = ((val >> 8)  & 0xff) ;
-       left = (val  & 0xff) ;
-
-       if(right > 100) right = 100;
-       if(left > 100) left = 100;
-
-       card->mix.mixer_state[mixer]=(right << 8) | left;
-       card->mix.write_mixer(card,mixer,left,right);
-}
-
-static void
-mixer_push_state(struct ess_card *card)
-{
-       int i;
-       for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) {
-               if( ! supported_mixer(card,i)) continue;
-
-               set_mixer(card,i,card->mix.mixer_state[i]);
-       }
-}
-
-static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
-{
-       int i, val=0;
-       unsigned long flags;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_CARD(card);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-               strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-               info.modify_counter = card->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-               strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-
-       if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-
-        if (_IOC_DIR(cmd) == _IOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* give them the current record source */
-
-                       if(!card->mix.recmask_io) {
-                               val = 0;
-                       } else {
-                               spin_lock_irqsave(&card->lock, flags);
-                               val = card->mix.recmask_io(card,1,0);
-                               spin_unlock_irqrestore(&card->lock, flags);
-                       }
-                       break;
-                       
-                case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
-                       val = card->mix.supported_mixers;
-                       break;
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       val = card->mix.record_sources;
-                       break;
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       val = card->mix.stereo_mixers;
-                       break;
-                       
-                case SOUND_MIXER_CAPS:
-                       val = SOUND_CAP_EXCL_INPUT;
-                       break;
-
-               default: /* read a specific mixer */
-                       i = _IOC_NR(cmd);
-
-                       if ( ! supported_mixer(card,i)) 
-                               return -EINVAL;
-
-                       /* do we ever want to touch the hardware? */
-/*                     spin_lock_irqsave(&card->lock, flags);
-                       val = card->mix.read_mixer(card,i);
-                       spin_unlock_irqrestore(&card->lock, flags);*/
-
-                       val = card->mix.mixer_state[i];
-/*                     M_printk("returned 0x%x for mixer %d\n",val,i);*/
-
-                       break;
-               }
-               return put_user(val, p);
-       }
-       
-        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
-               return -EINVAL;
-       
-       card->mix.modcnt++;
-
-       if (get_user(val, p))
-               return -EFAULT;
-
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-
-               if (!card->mix.recmask_io) return -EINVAL;
-               if(!val) return 0;
-               if(! (val &= card->mix.record_sources)) return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-               card->mix.recmask_io(card,0,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-
-               if ( ! supported_mixer(card,i)) 
-                       return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-               set_mixer(card,i,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-
-               return 0;
-       }
-}
-
-/* --------------------------------------------------------------------- */
-static int ess_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct ess_card *card = NULL;
-       struct pci_dev *pdev = NULL;
-       struct pci_driver *drvr;
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               drvr = pci_dev_driver (pdev);
-               if (drvr == &maestro_pci_driver) {
-                       card = (struct ess_card*)pci_get_drvdata (pdev);
-                       if (!card)
-                               continue;
-                       if (card->dev_mixer == minor)
-                               break;
-               }
-       }
-       if (!card)
-               return -ENODEV;
-       file->private_data = card;
-       return nonseekable_open(inode, file);
-}
-
-static int ess_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct ess_card *card = (struct ess_card *)file->private_data;
-
-       VALIDATE_CARD(card);
-       
-       return 0;
-}
-
-static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ess_card *card = (struct ess_card *)file->private_data;
-
-       VALIDATE_CARD(card);
-
-       return mixer_ioctl(card, cmd, arg);
-}
-
-static /*const*/ struct file_operations ess_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = ess_ioctl_mixdev,
-       .open           = ess_open_mixdev,
-       .release        = ess_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct ess_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait,current);
-       unsigned long flags;
-       int count;
-       signed long tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-       current->state = TASK_INTERRUPTIBLE;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               /* XXX uhm.. questionable locking*/
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                       current->state = TASK_RUNNING;
-                        return -EBUSY;
-                }
-               tmo = (count * HZ) / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-               /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-                       or something.  who cares. - zach */
-               if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-                       M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies);
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       current->state = TASK_RUNNING;
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* Zach sez: "god this is gross.." */
-static int 
-comb_stereo(unsigned char *real_buffer,unsigned char  *tmp_buffer, int offset, 
-       int count, int bufsize)
-{  
-       /* No such thing as stereo recording, so we
-       use dual input mixers.  which means we have to 
-       combine mono to stereo buffer.  yuck. 
-
-       but we don't have to be able to work a byte at a time..*/
-
-       unsigned char *so,*left,*right;
-       int i;
-
-       so = tmp_buffer;
-       left = real_buffer + offset;
-       right = real_buffer + bufsize/2 + offset;
-
-/*     M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/
-
-       for(i=count/4; i ; i--) {
-               (*(so+2)) = *(right++);
-               (*(so+3)) = *(right++);
-               (*so) = *(left++);
-               (*(so+1)) = *(left++);
-               so+=4;
-       }
-
-       return 0;
-}
-
-/* in this loop, dma_adc.count signifies the amount of data thats waiting
-       to be copied to the user's buffer.  it is filled by the interrupt
-       handler and drained by this loop. */
-static ssize_t 
-ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       unsigned char *combbuf = NULL;
-       
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if(!(combbuf = kmalloc(count,GFP_KERNEL)))
-               return -ENOMEM;
-       ret = 0;
-
-       calc_bob_rate(s);
-
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               /* remember, all these things are expressed in bytes to be
-                       sent to the user.. hence the evil / 2 down below */
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-
-               if ( cnt > 0 ) cnt &= ~3;
-
-               if (cnt <= 0) {
-                       start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) 
-                       {
-                               ret = ret ? ret : -EAGAIN;
-                               goto rec_return_free;
-                       }
-                       if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-                               if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               stop_adc(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                               /* program enhanced mode registers */
-                               /* FILL ME */
-/*                             wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) 
-                       {
-                               ret = ret ? ret : -ERESTARTSYS;
-                               goto rec_return_free;
-                       }
-                       continue;
-               }
-       
-               if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       /* swptr/2 so that we know the real offset in each apu's buffer */
-                       comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize);
-                       if (copy_to_user(buffer, combbuf, cnt)) {
-                               ret = ret ? ret : -EFAULT;
-                               goto rec_return_free;
-                       }
-               } else  {
-                       if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                               ret = ret ? ret : -EFAULT;
-                               goto rec_return_free;
-                       }
-               }
-
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_adc(s);
-       }
-
-rec_return_free:
-       kfree(combbuf);
-       return ret;
-}
-
-static ssize_t 
-ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-       calc_bob_rate(s);
-
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-
-               cnt = s->dma_dac.dmasize-swptr;
-
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt <= 0) {
-                       start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if(!ret) ret = -EAGAIN;
-                               goto return_free;
-                       }
-                       if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-                               if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               stop_dac(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                               /* program enhanced mode registers */
-/*                             wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); */
-                               /* FILL ME */
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               goto return_free;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       goto return_free;
-               }
-/*             printk("wrote %d bytes at sw: %d cnt: %d while hw: %d\n",cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);*/
-
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_dac(s);
-       }
-return_free:
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-
-/* In 0.14 prog_dmabuf always returns success anyway ... */
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 0)) 
-                       return 0;
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-                       return 0;
-       }
-
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->dma_dac.wait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->dma_adc.wait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       ess_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int ess_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else 
-#if 0
-       /* if we can have the wp/wc do the combining
-               we can turn this back on.  */
-             if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else  
-#endif
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-/*     printk("maestro: ess_ioctl: cmd %d\n", cmd);*/
-       
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, file->f_flags & O_NONBLOCK);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               /* XXX fix */
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->card->pcidev->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->card->pcidev->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-               
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                       else
-                               fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                       else
-                               fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_U8|AFMT_S16_LE, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-       /* fixed at 16bit for now */
-                               fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-#if 0
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-#endif
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-                       (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-                               AFMT_S16_LE : 
-                               AFMT_U8, 
-                       p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-                       val |= PCM_ENABLE_INPUT;
-               if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               start_dac(s);
-                       } else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               M_printk("maestro: SETFRAGMENT: %0x\n",val);
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return -EINVAL;
-}
-
-static void
-set_base_registers(struct ess_state *s,void *vaddr)
-{
-       unsigned long packed_phys = virt_to_bus(vaddr)>>12;
-       wave_set_register(s, 0x01FC , packed_phys);
-       wave_set_register(s, 0x01FD , packed_phys);
-       wave_set_register(s, 0x01FE , packed_phys);
-       wave_set_register(s, 0x01FF , packed_phys);
-}
-
-/* 
- * this guy makes sure we're in the right power
- * state for what we want to be doing 
- */
-static void maestro_power(struct ess_card *card, int tostate)
-{
-       u16 active_mask = acpi_state_mask[tostate];
-       u8 state;
-
-       if(!use_pm) return;
-
-       pci_read_config_byte(card->pcidev, card->power_regs+0x4, &state);
-       state&=3;
-
-       /* make sure we're in the right state */
-       if(state != tostate) {
-               M_printk(KERN_WARNING "maestro: dev %02x:%02x.%x switching from D%d to D%d\n",
-                       card->pcidev->bus->number, 
-                       PCI_SLOT(card->pcidev->devfn),
-                       PCI_FUNC(card->pcidev->devfn),
-                       state,tostate);
-               pci_write_config_byte(card->pcidev, card->power_regs+0x4, tostate);
-       }
-
-       /* and make sure the units we care about are on 
-               XXX we might want to do this before state flipping? */
-       pci_write_config_word(card->pcidev, 0x54, ~ active_mask);
-       pci_write_config_word(card->pcidev, 0x56, ~ active_mask);
-}
-
-/* we allocate a large power of two for all our memory.
-       this is cut up into (not to scale :):
-       |silly fifo word        | 512byte mixbuf per adc        | dac/adc * channels |
-*/
-static int
-allocate_buffers(struct ess_state *s)
-{
-       void *rawbuf=NULL;
-       int order,i;
-       struct page *page, *pend;
-
-       /* alloc as big a chunk as we can */
-       for (order = (dsps_order + (16-PAGE_SHIFT) + 1); order >= (dsps_order + 2 + 1); order--)
-               if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
-                       break;
-
-       if (!rawbuf)
-               return 1;
-
-       M_printk("maestro: allocated %ld (%d) bytes at %p\n",PAGE_SIZE<<order,order, rawbuf);
-
-       if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1))  {
-               printk(KERN_ERR "maestro: DMA buffer beyond 256MB! busaddr 0x%lx  size %ld\n",
-                       virt_to_bus(rawbuf), PAGE_SIZE << order);
-               kfree(rawbuf);
-               return 1;
-       }
-
-       s->card->dmapages = rawbuf;
-       s->card->dmaorder = order;
-
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *ess = &s->card->channels[i];
-
-               if(ess->dev_audio == -1)
-                       continue;
-
-               ess->dma_dac.ready = s->dma_dac.mapped = 0;
-               ess->dma_adc.ready = s->dma_adc.mapped = 0;
-               ess->dma_adc.buforder = ess->dma_dac.buforder = order - 1 - dsps_order - 1;
-
-               /* offset dac and adc buffers starting half way through and then at each [da][ad]c's
-                       order's intervals.. */
-               ess->dma_dac.rawbuf = rawbuf + (PAGE_SIZE<<(order-1)) + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 )));
-               ess->dma_adc.rawbuf = ess->dma_dac.rawbuf + ( PAGE_SIZE << ess->dma_dac.buforder);
-               /* offset mixbuf by a mixbuf so that the lame status fifo can
-                       happily scribble away.. */ 
-               ess->mixbuf = rawbuf + (512 * (i+1));
-
-               M_printk("maestro: setup apu %d: dac: %p adc: %p mix: %p\n",i,ess->dma_dac.rawbuf,
-                       ess->dma_adc.rawbuf, ess->mixbuf);
-
-       }
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (page = virt_to_page(rawbuf); page <= pend; page++)
-               SetPageReserved(page);
-
-       return 0;
-} 
-static void
-free_buffers(struct ess_state *s)
-{
-       struct page *page, *pend;
-
-       s->dma_dac.rawbuf = s->dma_adc.rawbuf = NULL;
-       s->dma_dac.mapped = s->dma_adc.mapped = 0;
-       s->dma_dac.ready = s->dma_adc.ready = 0;
-
-       M_printk("maestro: freeing %p\n",s->card->dmapages);
-       /* undo marking the pages as reserved */
-
-       pend = virt_to_page(s->card->dmapages + (PAGE_SIZE << s->card->dmaorder) - 1);
-       for (page = virt_to_page(s->card->dmapages); page <= pend; page++)
-               ClearPageReserved(page);
-
-       free_pages((unsigned long)s->card->dmapages,s->card->dmaorder);
-       s->card->dmapages = NULL;
-}
-
-static int 
-ess_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct ess_state *s = NULL;
-       unsigned char fmtm = ~0, fmts = 0;
-       struct pci_dev *pdev = NULL;
-       /*
-        *      Scan the cards and find the channel. We only
-        *      do this at open time so it is ok
-        */
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               struct ess_card *c;
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver (pdev);
-               if (drvr == &maestro_pci_driver) {
-                       int i;
-                       struct ess_state *sp;
-
-                       c = (struct ess_card*)pci_get_drvdata (pdev);
-                       if (!c)
-                               continue;
-                       for(i=0;i<NR_DSPS;i++)
-                       {
-                               sp=&c->channels[i];
-                               if(sp->dev_audio < 0)
-                                       continue;
-                               if((sp->dev_audio ^ minor) & ~0xf)
-                                       continue;
-                               s=sp;
-                       }
-               }
-       }
-       if (!s)
-               return -ENODEV;
-
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EWOULDBLOCK;
-               }
-               mutex_unlock(&s->open_mutex);
-               interruptible_sleep_on(&s->open_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-
-       /* under semaphore.. */
-       if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
-               mutex_unlock(&s->open_mutex);
-               return -ENOMEM;
-       }
-
-       /* we're covered by the open_mutex */
-       if( ! s->card->dsps_open )  {
-               maestro_power(s->card,ACPI_D0);
-               start_bob(s);
-       }
-       s->card->dsps_open++;
-       M_printk("maestro: open, %d bobs now\n",s->card->dsps_open);
-
-       /* ok, lets write WC base regs now that we've 
-               powered up the chip */
-       M_printk("maestro: writing 0x%lx (bus 0x%lx) to the wp\n",virt_to_bus(s->card->dmapages),
-               ((virt_to_bus(s->card->dmapages))&0xFFE00000)>>12);
-       set_base_registers(s,s->card->dmapages);
-
-       if (file->f_mode & FMODE_READ) {
-/*
-               fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */
-
-               fmtm &= ~((ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-               fmts = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT;
-
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               set_adc_rate(s, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               set_dac_rate(s, 8000);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int 
-ess_release(struct inode *inode, struct file *file)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-       }
-               
-       s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-       /* we're covered by the open_mutex */
-       M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
-       if( --s->card->dsps_open <= 0) {
-               s->card->dsps_open = 0;
-               stop_bob(s);
-               free_buffers(s);
-               maestro_power(s->card,ACPI_D2);
-       }
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static struct file_operations ess_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = ess_read,
-       .write          = ess_write,
-       .poll           = ess_poll,
-       .ioctl          = ess_ioctl,
-       .mmap           = ess_mmap,
-       .open           = ess_open,
-       .release        = ess_release,
-};
-
-static int
-maestro_config(struct ess_card *card) 
-{
-       struct pci_dev *pcidev = card->pcidev;
-       struct ess_state *ess = &card->channels[0];
-       int apu,iobase  = card->iobase;
-       u16 w;
-       u32 n;
-
-       /* We used to muck around with pci config space that
-        * we had no business messing with.  We don't know enough
-        * about the machine to know which DMA mode is appropriate, 
-        * etc.  We were guessing wrong on some machines and making
-        * them unhappy.  We now trust in the BIOS to do things right,
-        * which almost certainly means a new host of problems will
-        * arise with broken BIOS implementations.  screw 'em. 
-        * We're already intolerant of machines that don't assign
-        * IRQs.
-        */
-       
-       /* do config work at full power */
-       maestro_power(card,ACPI_D0);
-        
-       pci_read_config_word(pcidev, 0x50, &w);
-
-       w&=~(1<<5);                     /* Don't swap left/right (undoc)*/
-       
-       pci_write_config_word(pcidev, 0x50, w);
-       
-       pci_read_config_word(pcidev, 0x52, &w);
-       w&=~(1<<15);            /* Turn off internal clock multiplier */
-       /* XXX how do we know which to use? */
-       w&=~(1<<14);            /* External clock */
-       
-       w|= (1<<7);             /* Hardware volume control on */
-       w|= (1<<6);             /* Debounce off: easier to push the HWV buttons. */
-       w&=~(1<<5);             /* GPIO 4:5 */
-       w|= (1<<4);             /* Disconnect from the CHI.  Enabling this made a dell 7500 work. */
-       w&=~(1<<2);             /* MIDI fix off (undoc) */
-       w&=~(1<<1);             /* reserved, always write 0 */
-       pci_write_config_word(pcidev, 0x52, w);
-       
-       /*
-        *      Legacy mode
-        */
-
-       pci_read_config_word(pcidev, 0x40, &w);
-       w|=(1<<15);     /* legacy decode off */
-       w&=~(1<<14);    /* Disable SIRQ */
-       w&=~(0x1f);     /* disable mpu irq/io, game port, fm, SB */
-        
-       pci_write_config_word(pcidev, 0x40, w);
-
-       /* Set up 978 docking control chip. */
-       pci_read_config_word(pcidev, 0x58, &w);
-       w|=1<<2;        /* Enable 978. */
-       w|=1<<3;        /* Turn on 978 hardware volume control. */
-       w&=~(1<<11);    /* Turn on 978 mixer volume control. */
-       pci_write_config_word(pcidev, 0x58, w);
-       
-       sound_reset(iobase);
-
-       /*
-        *      Ring Bus Setup
-        */
-
-       /* setup usual 0x34 stuff.. 0x36 may be chip specific */
-        outw(0xC090, iobase+0x34); /* direct sound, stereo */
-        udelay(20);
-        outw(0x3000, iobase+0x36); /* direct sound, stereo */
-        udelay(20);
-
-
-       /*
-        *      Reset the CODEC
-        */
-        
-       maestro_ac97_reset(iobase,pcidev);
-       
-       /*
-        *      Ring Bus Setup
-        */
-                
-       n=inl(iobase+0x34);
-       n&=~0xF000;
-       n|=12<<12;              /* Direct Sound, Stereo */
-       outl(n, iobase+0x34);
-
-       n=inl(iobase+0x34);
-       n&=~0x0F00;             /* Modem off */
-       outl(n, iobase+0x34);
-
-       n=inl(iobase+0x34);
-       n&=~0x00F0;
-       n|=9<<4;                /* DAC, Stereo */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x000F;             /* ASSP off */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n|=(1<<29);             /* Enable ring bus */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n|=(1<<28);             /* Enable serial bus */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x00F00000;         /* MIC off */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x000F0000;         /* I2S off */
-       outl(n, iobase+0x34);
-       
-
-       w=inw(iobase+0x18);
-       w&=~(1<<7);             /* ClkRun off */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w&=~(1<<6);             /* Hardware volume control interrupt off... for now. */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w&=~(1<<4);             /* ASSP irq off */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w&=~(1<<3);             /* ISDN irq off */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w|=(1<<2);              /* Direct Sound IRQ on */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w&=~(1<<1);             /* MPU401 IRQ off */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w|=(1<<0);              /* SB IRQ on */
-       outw(w, iobase+0x18);
-
-       /* Set hardware volume control registers to midpoints.
-          We can tell which button was pushed based on how they change. */
-       outb(0x88, iobase+0x1c);
-       outb(0x88, iobase+0x1d);
-       outb(0x88, iobase+0x1e);
-       outb(0x88, iobase+0x1f);
-
-       /* it appears some maestros (dell 7500) only work if these are set,
-               regardless of whether we use the assp or not. */
-
-       outb(0, iobase+0xA4); 
-       outb(3, iobase+0xA2); 
-       outb(0, iobase+0xA6);
-       
-       for(apu=0;apu<16;apu++)
-       {
-               /* Write 0 into the buffer area 0x1E0->1EF */
-               outw(0x01E0+apu, 0x10+iobase);
-               outw(0x0000, 0x12+iobase);
-       
-               /*
-                * The 1.10 test program seem to write 0 into the buffer area
-                * 0x1D0-0x1DF too.
-                */
-               outw(0x01D0+apu, 0x10+iobase);
-               outw(0x0000, 0x12+iobase);
-       }
-
-#if 1
-       wave_set_register(ess, IDR7_WAVE_ROMRAM, 
-               (wave_get_register(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)|0x100);
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)&~0x200);
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)|~0x400);
-#else          
-       maestro_write(ess, IDR7_WAVE_ROMRAM, 
-               (maestro_read(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)|0x100);
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)&~0x200);
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)|0x400);
-#endif
-       
-       maestro_write(ess, IDR2_CRAM_DATA, 0x0000);
-       maestro_write(ess, 0x08, 0xB004);
-       /* Now back to the DirectSound stuff */
-       maestro_write(ess, 0x09, 0x001B);
-       maestro_write(ess, 0x0A, 0x8000);
-       maestro_write(ess, 0x0B, 0x3F37);
-       maestro_write(ess, 0x0C, 0x0098);
-       
-       /* parallel out ?? */
-       maestro_write(ess, 0x0C, 
-               (maestro_read(ess, 0x0C)&~0xF000)|0x8000); 
-       /* parallel in, has something to do with recording :) */
-       maestro_write(ess, 0x0C, 
-               (maestro_read(ess, 0x0C)&~0x0F00)|0x0500);
-
-       maestro_write(ess, 0x0D, 0x7632);
-                       
-       /* Wave cache control on - test off, sg off, 
-               enable, enable extra chans 1Mb */
-
-       outw(inw(0x14+iobase)|(1<<8),0x14+iobase);
-       outw(inw(0x14+iobase)&0xFE03,0x14+iobase);
-       outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase);
-       outw(inw(0x14+iobase)|(1<<7),0x14+iobase);
-
-       outw(0xA1A0, 0x14+iobase);      /* 0300 ? */
-
-       /* Now clear the APU control ram */     
-       for(apu=0;apu<NR_APUS;apu++)
-       {
-               for(w=0;w<NR_APU_REGS;w++)
-                       apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0);
-               
-       }
-
-       return 0;
-       
-}
-
-/* this guy tries to find the pci power management
- * register bank.  this should really be in core
- * code somewhere.  1 on success. */
-static int
-parse_power(struct ess_card *card, struct pci_dev *pcidev)
-{
-       u32 n;
-       u16 w;
-       u8 next;
-       int max = 64;  /* an a 8bit guy pointing to 32bit guys
-                               can only express so much. */
-
-       card->power_regs = 0;
-
-       /* check to see if we have a capabilities list in
-               the config register */
-       pci_read_config_word(pcidev, PCI_STATUS, &w);
-       if(!(w & PCI_STATUS_CAP_LIST)) return 0;
-
-       /* walk the list, starting at the head. */
-       pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next);
-
-       while(next && max--) {
-               pci_read_config_dword(pcidev, next & ~3, &n);
-               if((n & 0xff) == PCI_CAP_ID_PM) {
-                       card->power_regs = next;
-                       break;
-               }
-               next = ((n>>8) & 0xff);
-       }
-
-       return card->power_regs ? 1 : 0;
-}
-
-static int __init
-maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
-{
-       int card_type = pdid->driver_data;
-       u32 n;
-       int iobase;
-       int i, ret;
-       struct ess_card *card;
-       struct ess_state *ess;
-       int num = 0;
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-       static int printed_version;
-       if (!printed_version++)
-               printk(version);
-#endif
-
-       /* don't pick up weird modem maestros */
-       if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-               return -ENODEV;
-
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-                       
-       iobase = pci_resource_start(pcidev,0);
-       if (!iobase || !(pci_resource_flags(pcidev, 0 ) & IORESOURCE_IO))
-               return -ENODEV;
-
-       if(pcidev->irq == 0)
-               return -ENODEV;
-
-       /* stake our claim on the iospace */
-       if( request_region(iobase, 256, card_names[card_type]) == NULL )
-       {
-               printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
-               return -EBUSY;
-       }
-
-       /* just to be sure */
-       pci_set_master(pcidev);
-
-       card = kmalloc(sizeof(struct ess_card), GFP_KERNEL);
-       if(card == NULL)
-       {
-               printk(KERN_WARNING "maestro: out of memory\n");
-               release_region(iobase, 256);
-               return -ENOMEM;
-       }
-       
-       memset(card, 0, sizeof(*card));
-       card->pcidev = pcidev;
-
-       card->iobase = iobase;
-       card->card_type = card_type;
-       card->irq = pcidev->irq;
-       card->magic = ESS_CARD_MAGIC;
-       spin_lock_init(&card->lock);
-       init_waitqueue_head(&card->suspend_queue);
-
-       card->dock_mute_vol = 50;
-       
-       /* init our groups of 6 apus */
-       for(i=0;i<NR_DSPS;i++)
-       {
-               struct ess_state *s=&card->channels[i];
-
-               s->index = i;
-
-               s->card = card;
-               init_waitqueue_head(&s->dma_adc.wait);
-               init_waitqueue_head(&s->dma_dac.wait);
-               init_waitqueue_head(&s->open_wait);
-               spin_lock_init(&s->lock);
-               mutex_init(&s->open_mutex);
-               s->magic = ESS_STATE_MAGIC;
-               
-               s->apu[0] = 6*i;
-               s->apu[1] = (6*i)+1;
-               s->apu[2] = (6*i)+2;
-               s->apu[3] = (6*i)+3;
-               s->apu[4] = (6*i)+4;
-               s->apu[5] = (6*i)+5;
-               
-               if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-                       printk("maestro: BOTCH!\n");
-               /* register devices */
-               if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0)
-                       break;
-       }
-       
-       num = i;
-       
-       /* clear the rest if we ran out of slots to register */
-       for(;i<NR_DSPS;i++)
-       {
-               struct ess_state *s=&card->channels[i];
-               s->dev_audio = -1;
-       }
-       
-       ess = &card->channels[0];
-
-       /*
-        *      Ok card ready. Begin setup proper
-        */
-
-       printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", 
-               card_names[card_type],iobase,card->irq);
-       pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-       printk(KERN_INFO "maestro:  subvendor id: 0x%08x\n",n); 
-
-       /* turn off power management unless:
-        *      - the user explicitly asks for it
-        *              or
-        *              - we're not a 2e, lesser chipps seem to have problems.
-        *              - we're not on our _very_ small whitelist.  some implemenetations
-        *                      really don't like the pm code, others require it.
-        *                      feel free to expand this as required.
-        */
-#define SUBSYSTEM_VENDOR(x) (x&0xffff)
-       if(     (use_pm != 1) && 
-               ((card_type != TYPE_MAESTRO2E)  || (SUBSYSTEM_VENDOR(n) != 0x1028)))
-                       use_pm = 0;
-
-       if(!use_pm) 
-               printk(KERN_INFO "maestro: not attempting power management.\n");
-       else {
-               if(!parse_power(card,pcidev)) 
-                       printk(KERN_INFO "maestro: no PCI power management interface found.\n");
-               else {
-                       pci_read_config_dword(pcidev, card->power_regs, &n);
-                       printk(KERN_INFO "maestro: PCI power management capability: 0x%x\n",n>>16);
-               }       
-       }
-
-       maestro_config(card);
-
-       if(maestro_ac97_get(card, 0x00)==0x0080) {
-               printk(KERN_ERR "maestro: my goodness!  you seem to have a pt101 codec, which is quite rare.\n"
-                               "\tyou should tell someone about this.\n");
-       } else {
-               maestro_ac97_init(card);
-       }
-
-       if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) {
-               printk("maestro: couldn't register mixer!\n");
-       } else {
-               memcpy(card->mix.mixer_state,mixer_defaults,sizeof(card->mix.mixer_state));
-               mixer_push_state(card);
-       }
-       
-       if((ret=request_irq(card->irq, ess_interrupt, IRQF_SHARED, card_names[card_type], card)))
-       {
-               printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq);
-               unregister_sound_mixer(card->dev_mixer);
-               for(i=0;i<NR_DSPS;i++)
-               {
-                       struct ess_state *s = &card->channels[i];
-                       if(s->dev_audio != -1)
-                               unregister_sound_dsp(s->dev_audio);
-               }
-               release_region(card->iobase, 256);              
-               unregister_reboot_notifier(&maestro_nb);
-               kfree(card);
-               return ret;
-       }
-
-       /* Turn on hardware volume control interrupt.
-          This has to come after we grab the IRQ above,
-          or a crash will result on installation if a button has been pressed,
-          because in that case we'll get an immediate interrupt. */
-       n = inw(iobase+0x18);
-       n|=(1<<6);
-       outw(n, iobase+0x18);
-
-       pci_set_drvdata(pcidev,card);
-       /* now go to sleep 'till something interesting happens */
-       maestro_power(card,ACPI_D2);
-
-       printk(KERN_INFO "maestro: %d channels configured.\n", num);
-       return 0;
-}
-
-static void maestro_remove(struct pci_dev *pcidev) {
-       struct ess_card *card = pci_get_drvdata(pcidev);
-       int i;
-       u32 n;
-       
-       /* XXX maybe should force stop bob, but should be all 
-               stopped by _release by now */
-
-       /* Turn off hardware volume control interrupt.
-          This has to come before we leave the IRQ below,
-          or a crash results if a button is pressed ! */
-       n = inw(card->iobase+0x18);
-       n&=~(1<<6);
-       outw(n, card->iobase+0x18);
-
-       free_irq(card->irq, card);
-       unregister_sound_mixer(card->dev_mixer);
-       for(i=0;i<NR_DSPS;i++)
-       {
-               struct ess_state *ess = &card->channels[i];
-               if(ess->dev_audio != -1)
-                       unregister_sound_dsp(ess->dev_audio);
-       }
-       /* Goodbye, Mr. Bond. */
-       maestro_power(card,ACPI_D3);
-       release_region(card->iobase, 256);
-       kfree(card);
-       pci_set_drvdata(pcidev,NULL);
-}
-
-static struct pci_device_id maestro_pci_tbl[] = {
-       {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2},
-       {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2E},
-       {PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO},
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, maestro_pci_tbl);
-
-static struct pci_driver maestro_pci_driver = {
-       .name     = "maestro",
-       .id_table = maestro_pci_tbl,
-       .probe    = maestro_probe,
-       .remove   = maestro_remove,
-};
-
-static int __init init_maestro(void)
-{
-       int rc;
-
-       rc = pci_register_driver(&maestro_pci_driver);
-       if (rc < 0)
-               return rc;
-
-       if (register_reboot_notifier(&maestro_nb))
-               printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n");
-#ifdef MODULE
-       printk(version);
-#endif
-       if (dsps_order < 0)   {
-               dsps_order = 1;
-               printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-       }
-       else if (dsps_order > MAX_DSP_ORDER)  {
-               dsps_order = MAX_DSP_ORDER;
-               printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-       }
-       return 0;
-}
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-       /* this notifier is called when the kernel is really shut down. */
-       M_printk("maestro: shutting down\n");
-       /* this will remove all card instances too */
-       pci_unregister_driver(&maestro_pci_driver);
-       /* XXX dunno about power management */
-       return NOTIFY_OK;
-}
-
-/* --------------------------------------------------------------------- */
-
-
-static void cleanup_maestro(void) {
-       M_printk("maestro: unloading\n");
-       pci_unregister_driver(&maestro_pci_driver);
-       unregister_reboot_notifier(&maestro_nb);
-}
-
-/* --------------------------------------------------------------------- */
-
-void
-check_suspend(struct ess_card *card)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       if(!card->in_suspend) return;
-
-       card->in_suspend++;
-       add_wait_queue(&(card->suspend_queue), &wait);
-       current->state = TASK_UNINTERRUPTIBLE;
-       schedule();
-       remove_wait_queue(&(card->suspend_queue), &wait);
-       current->state = TASK_RUNNING;
-}
-
-module_init(init_maestro);
-module_exit(cleanup_maestro);
diff --git a/sound/oss/maestro.h b/sound/oss/maestro.h
deleted file mode 100644 (file)
index 023ec7f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *     Registers for the ESS PCI cards
- */
-/*
- *     Memory access
- */
-#define ESS_MEM_DATA           0x00
-#define        ESS_MEM_INDEX           0x02
-
-/*
- *     AC-97 Codec port. Delay 1uS after each write. This is used to
- *     talk AC-97 (see intel.com). Write data then register.
- */
-#define ESS_AC97_INDEX         0x30            /* byte wide */
-#define ESS_AC97_DATA          0x32
-
-/* 
- *     Reading is a bit different. You write register|0x80 to ubdex
- *     delay 1uS poll the low bit of index, when it clears read the
- *     data value.
- */
-
-/*
- *     Control port. Not yet fully understood
- *     The value 0xC090 gets loaded to it then 0x0000 and 0x2800
- *     to the data port. Then after 4uS the value 0x300 is written
- */
-#define RING_BUS_CTRL_L                0x34
-#define RING_BUS_CTRL_H                0x36
-
-/*
- *     This is also used during setup. The value 0x17 is written to it
- */
-#define ESS_SETUP_18           0x18
-
-/*
- *     And this one gets 0x000b
- */
-#define ESS_SETUP_A2           0xA2
-
-/*
- *     And this 0x0000
- */
-#define ESS_SETUP_A4           0xA4
-#define ESS_SETUP_A6           0xA6
-
-/*
- *     Stuff to do with Harpo - the wave stuff
- */
-#define ESS_WAVETABLE_SIZE     0x14
-#define        ESS_WAVETABLE_2M        0xA180
-
diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c
deleted file mode 100644 (file)
index 5548e3c..0000000
+++ /dev/null
@@ -1,2969 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro3/Allegro driver for Linux 2.4.x
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *    (c) Copyright 2000 Zach Brown <zab@zabbo.net>
- *
- * I need to thank many people for helping make this driver happen.  
- * As always, Eric Brombaugh was a hacking machine and killed many bugs
- * that I was too dumb to notice.  Howard Kim at ESS provided reference boards 
- * and as much docs as he could.  Todd and Mick at Dell tested snapshots on 
- * an army of laptops.  msw and deviant at Red Hat also humoured me by hanging
- * their laptops every few hours in the name of science.
- * 
- * Shouts go out to Mike "DJ XPCom" Ang.
- *
- * History
- *  v1.23 - Jun 5 2002 - Michael Olson <olson@cs.odu.edu>
- *   added a module option to allow selection of GPIO pin number 
- *   for external amp 
- *  v1.22 - Feb 28 2001 - Zach Brown <zab@zabbo.net>
- *   allocate mem at insmod/setup, rather than open
- *   limit pci dma addresses to 28bit, thanks guys.
- *  v1.21 - Feb 04 2001 - Zach Brown <zab@zabbo.net>
- *   fix up really dumb notifier -> suspend oops
- *  v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net>
- *   get rid of pm callback and use pci_dev suspend/resume instead
- *   m3_probe cleanups, including pm oops think-o
- *  v1.10 - Jan 6 2001 - Zach Brown <zab@zabbo.net>
- *   revert to lame remap_page_range mmap() just to make it work
- *   record mmap fixed.
- *   fix up incredibly broken open/release resource management
- *   duh.  fix record format setting.
- *   add SMP locking and cleanup formatting here and there
- *  v1.00 - Dec 16 2000 - Zach Brown <zab@zabbo.net>
- *   port to sexy 2.4 interfaces
- *   properly align instance allocations so recording works
- *   clean up function namespace a little :/
- *   update PCI IDs based on mail from ESS
- *   arbitrarily bump version number to show its 2.4 now, 
- *      2.2 will stay 0., oss_audio port gets 2.
- *  v0.03 - Nov 05 2000 - Zach Brown <zab@zabbo.net>
- *   disable recording but allow dsp to be opened read 
- *   pull out most silly compat defines
- *  v0.02 - Nov 04 2000 - Zach Brown <zab@zabbo.net>
- *   changed clocking setup for m3, slowdown fixed.
- *   codec reset is hopefully reliable now
- *   rudimentary apm/power management makes suspend/resume work
- *  v0.01 - Oct 31 2000 - Zach Brown <zab@zabbo.net>
- *   first release
- *  v0.00 - Sep 09 2000 - Zach Brown <zab@zabbo.net>
- *   first pass derivation from maestro.c
- *
- * TODO
- *  in/out allocated contiguously so fullduplex mmap will work?
- *  no beep on init (mute)
- *  resetup msrc data memory if freq changes?
- *
- *  --
- *
- *  Allow me to ramble a bit about the m3 architecture.  The core of the
- *  chip is the 'assp', the custom ESS dsp that runs the show.  It has
- *  a small amount of code and data ram.  ESS drops binary dsp code images
- *  on our heads, but we don't get to see specs on the dsp.  
- *
- *  The constant piece of code on the dsp is the 'kernel'.  It also has a 
- *  chunk of the dsp memory that is statically set aside for its control
- *  info.  This is the KDATA defines in maestro3.h.  Part of its core
- *  data is a list of code addresses that point to the pieces of DSP code
- *  that it should walk through in its loop.  These other pieces of code
- *  do the real work.  The kernel presumably jumps into each of them in turn.
- *  These code images tend to have their own data area, and one can have
- *  multiple data areas representing different states for each of the 'client
- *  instance' code portions.  There is generally a list in the kernel data
- *  that points to the data instances for a given piece of code.
- *
- *  We've only been given the binary image for the 'minisrc', mini sample 
- *  rate converter.  This is rather annoying because it limits the work
- *  we can do on the dsp, but it also greatly simplifies the job of managing
- *  dsp data memory for the code and data for our playing streams :).  We
- *  statically allocate the minisrc code into a region we 'know' to be free
- *  based on the map of the binary kernel image we're loading.  We also 
- *  statically allocate the data areas for the maximum number of pcm streams
- *  we can be dealing with.  This max is set by the length of the static list
- *  in the kernel data that records the number of minisrc data regions we
- *  can have.  Thats right, all software dsp mixing with static code list
- *  limits.  Rock.
- *
- *  How sound goes in and out is still a relative mystery.  It appears
- *  that the dsp has the ability to get input and output through various
- *  'connections'.  To do IO from or to a connection, you put the address
- *  of the minisrc client area in the static kernel data lists for that 
- *  input or output.  so for pcm -> dsp -> mixer, we put the minisrc data
- *  instance in the DMA list and also in the list for the mixer.  I guess
- *  it Just Knows which is in/out, and we give some dma control info that
- *  helps.  There are all sorts of cool inputs/outputs that it seems we can't
- *  use without dsp code images that know how to use them.
- *
- *  So at init time we preload all the memory allocation stuff and set some
- *  system wide parameters.  When we really get a sound to play we build
- *  up its minisrc header (stream parameters, buffer addresses, input/output
- *  settings).  Then we throw its header on the various lists.  We also
- *  tickle some KDATA settings that ask the assp to raise clock interrupts
- *  and do some amount of software mixing before handing data to the ac97.
- *
- *  Sorry for the vague details.  Feel free to ask Eric or myself if you
- *  happen to be trying to use this driver elsewhere.  Please accept my
- *  apologies for the quality of the OSS support code, its passed through
- *  too many hands now and desperately wants to be rethought.
- */
-
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/spinlock.h>
-#include <linux/ac97_codec.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include "maestro3.h"
-
-#define M_DEBUG 1
-
-#define DRIVER_VERSION      "1.23"
-#define M3_MODULE_NAME      "maestro3"
-#define PFX                 M3_MODULE_NAME ": "
-
-#define M3_STATE_MAGIC      0x734d724d
-#define M3_CARD_MAGIC       0x646e6f50
-
-#define ESS_FMT_STEREO      0x01
-#define ESS_FMT_16BIT       0x02
-#define ESS_FMT_MASK        0x03
-#define ESS_DAC_SHIFT       0   
-#define ESS_ADC_SHIFT       4
-
-#define DAC_RUNNING         1
-#define ADC_RUNNING         2
-
-#define SND_DEV_DSP16       5 
-   
-#ifdef M_DEBUG
-static int debug;
-#define DPMOD   1   /* per module load */
-#define DPSTR   2   /* per 'stream' */
-#define DPSYS   3   /* per syscall */
-#define DPCRAP  4   /* stuff the user shouldn't see unless they're really debuggin */
-#define DPINT   5   /* per interrupt, LOTS */
-#define DPRINTK(DP, args...) {if (debug >= (DP)) printk(KERN_DEBUG PFX args);}
-#else
-#define DPRINTK(x)
-#endif
-
-struct m3_list {
-    int curlen;
-    u16 mem_addr;
-    int max;
-};
-
-static int external_amp = 1;
-static int gpio_pin = -1;
-
-struct m3_state {
-    unsigned int magic;
-    struct m3_card *card;
-    unsigned char fmt, enable;
-
-    int index;
-
-    /* this locks around the oss state in the driver */
-       /* no, this lock is removed - only use card->lock */
-       /* otherwise: against what are you protecting on SMP 
-               when irqhandler uses s->lock
-               and m3_assp_read uses card->lock ?
-               */
-    struct mutex open_mutex;
-    wait_queue_head_t open_wait;
-    mode_t open_mode;
-
-    int dev_audio;
-
-    struct assp_instance {
-        u16 code, data;
-    } dac_inst, adc_inst;
-
-    /* should be in dmabuf */
-    unsigned int rateadc, ratedac;
-
-    struct dmabuf {
-        void *rawbuf;
-        unsigned buforder;
-        unsigned numfrag;
-        unsigned fragshift;
-        unsigned hwptr, swptr;
-        unsigned total_bytes;
-        int count;
-        unsigned error; /* over/underrun */
-        wait_queue_head_t wait;
-        /* redundant, but makes calculations easier */
-        unsigned fragsize;
-        unsigned dmasize;
-        unsigned fragsamples;
-        /* OSS stuff */
-        unsigned mapped:1;
-        unsigned ready:1;    
-        unsigned endcleared:1;
-        unsigned ossfragshift;
-        int ossmaxfrags;
-        unsigned subdivision;
-        /* new in m3 */
-        int mixer_index, dma_index, msrc_index, adc1_index;
-        int in_lists;
-        /* 2.4.. */
-        dma_addr_t handle;
-
-    } dma_dac, dma_adc;
-};
-    
-struct m3_card {
-    unsigned int magic;
-
-    struct m3_card *next;
-
-    struct ac97_codec *ac97;
-    spinlock_t ac97_lock;
-
-    int card_type;
-
-#define NR_DSPS 1
-#define MAX_DSPS NR_DSPS
-    struct m3_state channels[MAX_DSPS];
-
-    /* this locks around the physical registers on the card */
-    spinlock_t lock;
-
-    /* hardware resources */
-    struct pci_dev *pcidev;
-    u32 iobase;
-    u32 irq;
-
-    int dacs_active;
-
-    int timer_users;
-
-    struct m3_list  msrc_list,
-                    mixer_list,
-                    adc1_list,
-                    dma_list;
-
-    /* for storing reset state..*/
-    u8 reset_state;
-
-    u16 *suspend_mem;
-    int in_suspend;
-    wait_queue_head_t suspend_queue;
-};
-
-/*
- * an arbitrary volume we set the internal
- * volume settings to so that the ac97 volume
- * range is a little less insane.  0x7fff is 
- * max.
- */
-#define ARB_VOLUME ( 0x6800 )
-
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum {
-    ESS_ALLEGRO,
-    ESS_MAESTRO3,
-    /*
-     * a maestro3 with 'hardware strapping', only
-     * found inside ESS?
-     */
-    ESS_MAESTRO3HW,
-};
-
-static char *card_names[] = {
-    [ESS_ALLEGRO] = "Allegro",
-    [ESS_MAESTRO3] = "Maestro3(i)",
-    [ESS_MAESTRO3HW] = "Maestro3(i)hw"
-};
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS      0x125D
-#endif
-
-#define M3_DEVICE(DEV, TYPE)                   \
-{                                              \
-.vendor             = PCI_VENDOR_ESS,                  \
-.device             = DEV,                             \
-.subvendor   = PCI_ANY_ID,                     \
-.subdevice   = PCI_ANY_ID,                     \
-.class      = PCI_CLASS_MULTIMEDIA_AUDIO << 8, \
-.class_mask  = 0xffff << 8,                    \
-.driver_data = TYPE,                           \
-}
-
-static struct pci_device_id m3_id_table[] = {
-    M3_DEVICE(0x1988, ESS_ALLEGRO),
-    M3_DEVICE(0x1998, ESS_MAESTRO3),
-    M3_DEVICE(0x199a, ESS_MAESTRO3HW),
-    {0,}
-};
-
-MODULE_DEVICE_TABLE (pci, m3_id_table);
-
-/*
- * reports seem to indicate that the m3 is limited
- * to 28bit bus addresses.  aaaargggh...
- */
-#define M3_PCI_DMA_MASK 0x0fffffff
-
-static unsigned 
-ld2(unsigned int x)
-{
-    unsigned r = 0;
-    
-    if (x >= 0x10000) {
-        x >>= 16;
-        r += 16;
-    }
-    if (x >= 0x100) {
-        x >>= 8;
-        r += 8;
-    }
-    if (x >= 0x10) {
-        x >>= 4;
-        r += 4;
-    }
-    if (x >= 4) {
-        x >>= 2;
-        r += 2;
-    }
-    if (x >= 2)
-        r++;
-    return r;
-}
-
-static struct m3_card *devs;
-
-/*
- * I'm not very good at laying out functions in a file :)
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static void check_suspend(struct m3_card *card);
-
-static struct notifier_block m3_reboot_nb = {
-       .notifier_call = m3_notifier,
-};
-
-static void m3_outw(struct m3_card *card,
-        u16 value, unsigned long reg)
-{
-    check_suspend(card);
-    outw(value, card->iobase + reg);
-}
-
-static u16 m3_inw(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inw(card->iobase + reg);
-}
-static void m3_outb(struct m3_card *card, 
-        u8 value, unsigned long reg)
-{
-    check_suspend(card);
-    outb(value, card->iobase + reg);
-}
-static u8 m3_inb(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inb(card->iobase + reg);
-}
-
-/*
- * access 16bit words to the code or data regions of the dsp's memory.
- * index addresses 16bit words.
- */
-static u16 __m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    return m3_inw(card, DSP_PORT_MEMORY_DATA);
-}
-static u16 m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    unsigned long flags;
-    u16 ret;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    ret = __m3_assp_read(card, region, index);
-    spin_unlock_irqrestore(&(card->lock), flags);
-
-    return ret;
-}
-
-static void __m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    m3_outw(card, data, DSP_PORT_MEMORY_DATA);
-}
-static void m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    __m3_assp_write(card, region, index, data);
-    spin_unlock_irqrestore(&(card->lock), flags);
-}
-
-static void m3_assp_halt(struct m3_card *card)
-{
-    card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
-    mdelay(10);
-    m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-static void m3_assp_continue(struct m3_card *card)
-{
-    m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-/*
- * This makes me sad. the maestro3 has lists
- * internally that must be packed.. 0 terminates,
- * apparently, or maybe all unused entries have
- * to be 0, the lists have static lengths set
- * by the binary code images.
- */
-
-static int m3_add_list(struct m3_card *card,
-        struct m3_list *list, u16 val)
-{
-    DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n",
-            val, list, list->curlen);
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + list->curlen,
-            val);
-
-    return list->curlen++;
-
-}
-
-static void m3_remove_list(struct m3_card *card,
-        struct m3_list *list, int index)
-{
-    u16  val;
-    int lastindex = list->curlen - 1;
-
-    DPRINTK(DPSTR, "removing ind %d from list 0x%p\n",
-            index, list);
-
-    if(index != lastindex) {
-        val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + lastindex);
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + index,
-                val);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + lastindex,
-            0);
-
-    list->curlen--;
-}
-
-static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data)
-{
-    int tmp;
-
-    s->fmt = (s->fmt & mask) | data;
-
-    tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-
-    tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-}
-
-static void set_dac_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->ratedac = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void set_adc_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->rateadc = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void inc_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-    
-    card->timer_users++;
-    DPRINTK(DPSYS, "inc timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users != 1) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         240 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         240 ) ;
-
-    m3_outw(card,  
-            m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static void dec_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-
-    card->timer_users--;
-    DPRINTK(DPSYS, "dec timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users > 0 ) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         0 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         0 ) ;
-
-    m3_outw(card,  m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/*
- * {start,stop}_{adc,dac} should be called
- * while holding the 'state' lock and they
- * will try to grab the 'card' lock..
- */
-static void stop_adc(struct m3_state *s)
-{
-    if (! (s->enable & ADC_RUNNING)) 
-        return;
-
-    s->enable &= ~ADC_RUNNING;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 0);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 0);
-}    
-
-static void stop_dac(struct m3_state *s)
-{
-    if (! (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "stop_dac()\n");
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 0);
-
-    s->enable &= ~DAC_RUNNING;
-    s->card->dacs_active--;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_dac(struct m3_state *s)
-{
-    if( (!s->dma_dac.mapped && s->dma_dac.count < 1) ||
-            !s->dma_dac.ready ||
-            (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "start_dac()\n");
-
-    s->enable |= DAC_RUNNING;
-    s->card->dacs_active++;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_adc(struct m3_state *s)
-{
-    if ((! s->dma_adc.mapped &&
-                s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-        || !s->dma_adc.ready 
-        || (s->enable & ADC_RUNNING) ) 
-            return;
-
-    DPRINTK(DPSYS, "start_adc()\n");
-
-    s->enable |= ADC_RUNNING;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 1);
-}    
-
-static struct play_vals {
-    u16 addr, val;
-} pv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 0} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
-};
-
-
-/* the mode passed should be already shifted and masked */
-static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
-    int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_dac;
-    int i;
-
-    DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->dac_inst.data + 40 + 8);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19,
-        s->dac_inst.code + MINISRC_COEF_LOC);
-
-    /* enable or disable low pass filter? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22,
-        s->ratedac > 45000 ? 0xff : 0 );
-    
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + pv[i].addr, pv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->mixer_index = m3_add_list(s->card, &s->card->mixer_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_dac_rate(s,rate);
-    start_dac(s);
-}
-
-/*
- *    Native record driver 
- */
-static struct rec_vals {
-    u16 addr, val;
-} rv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 1} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
-    {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
-};
-
-/* again, passed mode is alrady shifted/masked */
-static void m3_rec_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
-    int dsp_in_buffer = s->adc_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_adc;
-    int i;
-
-    DPRINTK(DPSTR, "rec_setup mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->adc_inst.data + 40 + 8);
-
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT + 
-        DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + rv[i].addr, rv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->adc1_index = m3_add_list(s->card, &s->card->adc1_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_adc_rate(s,rate);
-    start_adc(s);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmaa??\n");
-}
-
-static void set_dmac(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmac??\n");
-}
-
-static u32 get_dma_pos(struct m3_card *card,
-                      int instance_addr)
-{
-    u16 hi = 0, lo = 0;
-    int retry = 10;
-
-    /*
-     * try and get a valid answer
-     */
-    while(retry--) {
-        hi =  m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH);
-
-        lo = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTL);
-
-        if(hi == m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH))
-            break;
-    }
-    return lo | (hi<<16);
-}
-
-static u32 get_dmaa(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->dac_inst.data) - 
-        virt_to_bus(s->dma_dac.rawbuf);
-
-    DPRINTK(DPINT,"get_dmaa: 0x%08x\n",offset);
-
-    return offset;
-}
-
-static u32 get_dmac(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->adc_inst.data) -
-        virt_to_bus(s->dma_adc.rawbuf);
-
-    DPRINTK(DPINT,"get_dmac: 0x%08x\n",offset);
-
-    return offset;
-
-}
-
-static int 
-prog_dmabuf(struct m3_state *s, unsigned rec)
-{
-    struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-    unsigned rate = rec ? s->rateadc : s->ratedac;
-    unsigned bytepersec;
-    unsigned bufs;
-    unsigned char fmt;
-    unsigned long flags;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    fmt = s->fmt;
-    if (rec) {
-        stop_adc(s);
-        fmt >>= ESS_ADC_SHIFT;
-    } else {
-        stop_dac(s);
-        fmt >>= ESS_DAC_SHIFT;
-    }
-    fmt &= ESS_FMT_MASK;
-
-    db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-    bytepersec = rate << sample_shift[fmt];
-    bufs = PAGE_SIZE << db->buforder;
-    if (db->ossfragshift) {
-        if ((1000 << db->ossfragshift) < bytepersec)
-            db->fragshift = ld2(bytepersec/1000);
-        else
-            db->fragshift = db->ossfragshift;
-    } else {
-        db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-        if (db->fragshift < 3)
-            db->fragshift = 3; 
-    }
-    db->numfrag = bufs >> db->fragshift;
-    while (db->numfrag < 4 && db->fragshift > 3) {
-        db->fragshift--;
-        db->numfrag = bufs >> db->fragshift;
-    }
-    db->fragsize = 1 << db->fragshift;
-    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-        db->numfrag = db->ossmaxfrags;
-    db->fragsamples = db->fragsize >> sample_shift[fmt];
-    db->dmasize = db->numfrag << db->fragshift;
-
-    DPRINTK(DPSTR,"prog_dmabuf: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-    memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-    if (rec) 
-        m3_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-    else 
-        m3_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-    db->ready = 1;
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-
-    return 0;
-}
-
-static void clear_advance(struct m3_state *s)
-{
-    unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-    
-    unsigned char *buf = s->dma_dac.rawbuf;
-    unsigned bsize = s->dma_dac.dmasize;
-    unsigned bptr = s->dma_dac.swptr;
-    unsigned len = s->dma_dac.fragsize;
-    
-    if (bptr + len > bsize) {
-        unsigned x = bsize - bptr;
-        memset(buf + bptr, c, x);
-        /* account for wrapping? */
-        bptr = 0;
-        len -= x;
-    }
-    memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void m3_update_ptr(struct m3_state *s)
-{
-    unsigned hwptr;
-    int diff;
-
-    /* update ADC pointer */
-    if (s->dma_adc.ready) {
-        hwptr = get_dmac(s) % s->dma_adc.dmasize;
-        diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-        s->dma_adc.hwptr = hwptr;
-        s->dma_adc.total_bytes += diff;
-        s->dma_adc.count += diff;
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-            wake_up(&s->dma_adc.wait);
-        if (!s->dma_adc.mapped) {
-            if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                stop_adc(s); 
-                /* brute force everyone back in sync, sigh */
-                s->dma_adc.count = 0;
-                s->dma_adc.swptr = 0;
-                s->dma_adc.hwptr = 0;
-                s->dma_adc.error++;
-            }
-        }
-    }
-    /* update DAC pointer */
-    if (s->dma_dac.ready) {
-        hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-        diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-
-        DPRINTK(DPINT,"updating dac: hwptr: %6d diff: %6d count: %6d\n",
-                hwptr,diff,s->dma_dac.count);
-
-        s->dma_dac.hwptr = hwptr;
-        s->dma_dac.total_bytes += diff;
-
-        if (s->dma_dac.mapped) {
-            
-            s->dma_dac.count += diff;
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-                wake_up(&s->dma_dac.wait);
-            }
-        } else {
-
-            s->dma_dac.count -= diff;
-            
-            if (s->dma_dac.count <= 0) {
-                DPRINTK(DPCRAP,"underflow! diff: %d (0x%x) count: %d (0x%x) hw: %d (0x%x) sw: %d (0x%x)\n", 
-                        diff, diff, 
-                        s->dma_dac.count, 
-                        s->dma_dac.count, 
-                    hwptr, hwptr,
-                    s->dma_dac.swptr,
-                    s->dma_dac.swptr);
-                stop_dac(s);
-                /* brute force everyone back in sync, sigh */
-                s->dma_dac.count = 0; 
-                s->dma_dac.swptr = hwptr; 
-                s->dma_dac.error++;
-            } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                clear_advance(s);
-                s->dma_dac.endcleared = 1;
-            }
-            if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-                wake_up(&s->dma_dac.wait);
-                DPRINTK(DPINT,"waking up DAC count: %d sw: %d hw: %d\n",
-                        s->dma_dac.count, s->dma_dac.swptr, hwptr);
-            }
-        }
-    }
-}
-
-static irqreturn_t m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct m3_card *c = (struct m3_card *)dev_id;
-    struct m3_state *s = &c->channels[0];
-    u8 status;
-
-    status = inb(c->iobase+0x1A);
-
-    if(status == 0xff)
-       return IRQ_NONE;
-   
-    /* presumably acking the ints? */
-    outw(status, c->iobase+0x1A); 
-
-    if(c->in_suspend)
-        return IRQ_HANDLED;
-
-    /*
-     * ack an assp int if its running
-     * and has an int pending
-     */
-    if( status & ASSP_INT_PENDING) {
-        u8 ctl = inb(c->iobase + ASSP_CONTROL_B);
-        if( !(ctl & STOP_ASSP_CLOCK)) {
-            ctl = inb(c->iobase + ASSP_HOST_INT_STATUS );
-            if(ctl & DSP2HOST_REQ_TIMER) {
-                outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS);
-                /* update adc/dac info if it was a timer int */
-                spin_lock(&c->lock);
-                m3_update_ptr(s);
-                spin_unlock(&c->lock);
-            }
-        }
-    }
-
-    /* XXX is this needed? */
-    if(status & 0x40) 
-        outb(0x40, c->iobase+0x1A);
-    return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-    if (!(FOO) || (FOO)->magic != MAG) { \
-        printk(invalid_magic,__FUNCTION__);            \
-        return -ENXIO;                    \
-    }                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,M3_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,M3_CARD_MAGIC)
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct m3_state *s, int nonblock)
-{
-    DECLARE_WAITQUEUE(wait,current);
-    unsigned long flags;
-    int count;
-    signed long tmo;
-
-    if (s->dma_dac.mapped || !s->dma_dac.ready)
-        return 0;
-    set_current_state(TASK_INTERRUPTIBLE);
-    add_wait_queue(&s->dma_dac.wait, &wait);
-    for (;;) {
-        spin_lock_irqsave(&s->card->lock, flags);
-        count = s->dma_dac.count;
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (count <= 0)
-            break;
-        if (signal_pending(current))
-            break;
-        if (nonblock) {
-            remove_wait_queue(&s->dma_dac.wait, &wait);
-            set_current_state(TASK_RUNNING);
-            return -EBUSY;
-        }
-        tmo = (count * HZ) / s->ratedac;
-        tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-        /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-            or something.  who cares. - zach */
-        if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-            DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
-    }
-    remove_wait_queue(&s->dma_dac.wait, &wait);
-    set_current_state(TASK_RUNNING);
-    if (signal_pending(current))
-            return -ERESTARTSYS;
-    return 0;
-}
-
-static ssize_t m3_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_adc.mapped)
-        return -ENXIO;
-    if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-        return ret;
-    if (!access_ok(VERIFY_WRITE, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        swptr = s->dma_adc.swptr;
-        cnt = s->dma_adc.dmasize-swptr;
-        if (s->dma_adc.count < cnt)
-            cnt = s->dma_adc.count;
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_adc(s);
-            if (file->f_flags & O_NONBLOCK) 
-            {
-                ret = ret ? ret : -EAGAIN;
-                goto out;
-            }
-
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-
-            if(timed_out) {
-                printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                       s->dma_adc.hwptr, s->dma_adc.swptr);
-                stop_adc(s);
-                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-            }
-            if (signal_pending(current)) 
-            {
-                ret = ret ? ret : -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-    
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-            ret = ret ? ret : -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        swptr = (swptr + cnt) % s->dma_adc.dmasize;
-        s->dma_adc.swptr = swptr;
-        s->dma_adc.count -= cnt;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_adc(s);
-    }
-
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static ssize_t m3_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_dac.mapped)
-        return -ENXIO;
-    if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-        return ret;
-    if (!access_ok(VERIFY_READ, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        if (s->dma_dac.count < 0) {
-            s->dma_dac.count = 0;
-            s->dma_dac.swptr = s->dma_dac.hwptr;
-        }
-        swptr = s->dma_dac.swptr;
-
-        cnt = s->dma_dac.dmasize-swptr;
-
-        if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-            cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_dac(s);
-            if (file->f_flags & O_NONBLOCK) {
-                if(!ret) ret = -EAGAIN;
-                goto out;
-            }
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-            if(timed_out) {
-                DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                       s->dma_dac.hwptr, s->dma_dac.swptr);
-                stop_dac(s);
-                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-            }
-            if (signal_pending(current)) {
-                if (!ret) ret = -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-            if (!ret) ret = -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",
-                cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);
-        
-        swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-        s->dma_dac.swptr = swptr;
-        s->dma_dac.count += cnt;
-        s->dma_dac.endcleared = 0;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_dac(s);
-    }
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long flags;
-    unsigned int mask = 0;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        poll_wait(file, &s->dma_dac.wait, wait);
-    if (file->f_mode & FMODE_READ)
-        poll_wait(file, &s->dma_adc.wait, wait);
-
-    spin_lock_irqsave(&s->card->lock, flags);
-    m3_update_ptr(s);
-
-    if (file->f_mode & FMODE_READ) {
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-            mask |= POLLIN | POLLRDNORM;
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        if (s->dma_dac.mapped) {
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                mask |= POLLOUT | POLLWRNORM;
-        } else {
-            if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                mask |= POLLOUT | POLLWRNORM;
-        }
-    }
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return mask;
-}
-
-static int m3_mmap(struct file *file, struct vm_area_struct *vma)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long max_size, size, start, offset;
-    struct dmabuf *db;
-    int ret = -EINVAL;
-
-    VALIDATE_STATE(s);
-    if (vma->vm_flags & VM_WRITE) {
-        if ((ret = prog_dmabuf(s, 0)) != 0)
-            return ret;
-        db = &s->dma_dac;
-    } else 
-    if (vma->vm_flags & VM_READ) {
-        if ((ret = prog_dmabuf(s, 1)) != 0)
-            return ret;
-        db = &s->dma_adc;
-    } else  
-        return -EINVAL;
-
-    max_size = db->dmasize;
-
-    start = vma->vm_start;
-    offset = (vma->vm_pgoff << PAGE_SHIFT);
-    size = vma->vm_end - vma->vm_start;
-
-    if(size > max_size)
-        goto out;
-    if(offset > max_size - size)
-        goto out;
-
-    /*
-     * this will be ->nopage() once I can 
-     * ask Jeff what the hell I'm doing wrong.
-     */
-    ret = -EAGAIN;
-    if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-        goto out;
-
-    db->mapped = 1;
-    ret = 0;
-
-out:
-    return ret;
-}
-
-/*
- * this function is a disaster..
- */
-#define get_user_ret(x, ptr,  ret) ({ if(get_user(x, ptr)) return ret; })
-static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-       struct m3_card *card=s->card;
-    unsigned long flags;
-    audio_buf_info abinfo;
-    count_info cinfo;
-    int val, mapped, ret;
-    unsigned char fmtm, fmtd;
-    void __user *argp = (void __user *)arg;
-    int __user *p = argp;
-
-    VALIDATE_STATE(s);
-
-    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-        ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-    DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd);
-
-    switch (cmd) {
-    case OSS_GETVERSION:
-        return put_user(SOUND_VERSION, p);
-
-    case SNDCTL_DSP_SYNC:
-        if (file->f_mode & FMODE_WRITE)
-            return drain_dac(s, file->f_flags & O_NONBLOCK);
-        return 0;
-        
-    case SNDCTL_DSP_SETDUPLEX:
-        /* XXX fix */
-        return 0;
-
-    case SNDCTL_DSP_GETCAPS:
-        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-        
-    case SNDCTL_DSP_RESET:
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-        }
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SPEED:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val >= 0) {
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                set_adc_rate(s, val);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                set_dac_rate(s, val);
-            }
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-        
-    case SNDCTL_DSP_STEREO:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        fmtd = 0;
-        fmtm = ~0;
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            s->dma_adc.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            s->dma_dac.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-        }
-        set_fmt(s, fmtm, fmtd);
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_CHANNELS:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != 0) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-        
-    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-        return put_user(AFMT_U8|AFMT_S16_LE, p);
-        
-    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != AFMT_QUERY) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-            (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-            : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-                AFMT_S16_LE : 
-                AFMT_U8, 
-            p);
-        
-    case SNDCTL_DSP_POST:
-        return 0;
-
-    case SNDCTL_DSP_GETTRIGGER:
-        val = 0;
-        if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-            val |= PCM_ENABLE_INPUT;
-        if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-            val |= PCM_ENABLE_OUTPUT;
-        return put_user(val, p);
-        
-    case SNDCTL_DSP_SETTRIGGER:
-        get_user_ret(val, p, -EFAULT);
-        if (file->f_mode & FMODE_READ) {
-            if (val & PCM_ENABLE_INPUT) {
-                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                    return ret;
-                start_adc(s);
-            } else
-                stop_adc(s);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            if (val & PCM_ENABLE_OUTPUT) {
-                if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                    return ret;
-                start_dac(s);
-            } else
-                stop_dac(s);
-        }
-        return 0;
-
-    case SNDCTL_DSP_GETOSPACE:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_dac.fragsize;
-        abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-        abinfo.fragstotal = s->dma_dac.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-    case SNDCTL_DSP_GETISPACE:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_adc.fragsize;
-        abinfo.bytes = s->dma_adc.count;
-        abinfo.fragstotal = s->dma_adc.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-        
-    case SNDCTL_DSP_NONBLOCK:
-        file->f_flags |= O_NONBLOCK;
-        return 0;
-
-    case SNDCTL_DSP_GETODELAY:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        val = s->dma_dac.count;
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user(val, p);
-
-    case SNDCTL_DSP_GETIPTR:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_adc.total_bytes;
-        cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-        cinfo.ptr = s->dma_adc.hwptr;
-        if (s->dma_adc.mapped)
-            s->dma_adc.count &= s->dma_adc.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-               return -EFAULT;
-       return 0;
-
-    case SNDCTL_DSP_GETOPTR:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_dac.total_bytes;
-        cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-        cinfo.ptr = s->dma_dac.hwptr;
-        if (s->dma_dac.mapped)
-            s->dma_dac.count &= s->dma_dac.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-               return -EFAULT;
-       return 0;
-
-    case SNDCTL_DSP_GETBLKSIZE:
-        if (file->f_mode & FMODE_WRITE) {
-            if ((val = prog_dmabuf(s, 0)))
-                return val;
-            return put_user(s->dma_dac.fragsize, p);
-        }
-        if ((val = prog_dmabuf(s, 1)))
-            return val;
-        return put_user(s->dma_adc.fragsize, p);
-
-    case SNDCTL_DSP_SETFRAGMENT:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_READ) {
-            s->dma_adc.ossfragshift = val & 0xffff;
-            s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_adc.ossfragshift < 4)
-                s->dma_adc.ossfragshift = 4;
-            if (s->dma_adc.ossfragshift > 15)
-                s->dma_adc.ossfragshift = 15;
-            if (s->dma_adc.ossmaxfrags < 4)
-                s->dma_adc.ossmaxfrags = 4;
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            s->dma_dac.ossfragshift = val & 0xffff;
-            s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_dac.ossfragshift < 4)
-                s->dma_dac.ossfragshift = 4;
-            if (s->dma_dac.ossfragshift > 15)
-                s->dma_dac.ossfragshift = 15;
-            if (s->dma_dac.ossmaxfrags < 4)
-                s->dma_dac.ossmaxfrags = 4;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SUBDIVIDE:
-        if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-            (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-            return -EINVAL;
-                get_user_ret(val, p, -EFAULT);
-        if (val != 1 && val != 2 && val != 4)
-            return -EINVAL;
-        if (file->f_mode & FMODE_READ)
-            s->dma_adc.subdivision = val;
-        if (file->f_mode & FMODE_WRITE)
-            s->dma_dac.subdivision = val;
-        return 0;
-
-    case SOUND_PCM_READ_RATE:
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-    case SOUND_PCM_READ_CHANNELS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-    case SOUND_PCM_READ_BITS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-    case SOUND_PCM_WRITE_FILTER:
-    case SNDCTL_DSP_SETSYNCRO:
-    case SOUND_PCM_READ_FILTER:
-        return -EINVAL;
-        
-    }
-    return -EINVAL;
-}
-
-static int
-allocate_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    int order;
-
-    DPRINTK(DPSTR,"allocating for dmabuf %p\n", db);
-
-    /* 
-     * alloc as big a chunk as we can, start with 
-     * 64k 'cause we're insane.  based on order cause
-     * the amazingly complicated prog_dmabuf wants it.
-     *
-     * pci_alloc_sonsistent guarantees that it won't cross a natural
-     * boundary; the m3 hardware can't have dma cross a 64k bus
-     * address boundary.
-     */
-    for (order = 16-PAGE_SHIFT; order >= 1; order--) {
-        db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order,
-                        &(db->handle));
-        if(db->rawbuf)
-            break;
-    }
-
-    if (!db->rawbuf)
-        return 1;
-
-    DPRINTK(DPSTR,"allocated %ld (%d) bytes at %p\n",
-            PAGE_SIZE<<order, order, db->rawbuf);
-
-    {
-        struct page *page, *pend;
-
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << order) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            SetPageReserved(page);
-    }
-
-
-    db->buforder = order;
-    db->ready = 0;
-    db->mapped = 0;
-
-    return 0;
-}
-
-static void
-nuke_lists(struct m3_card *card, struct dmabuf *db)
-{
-    m3_remove_list(card, &(card->dma_list), db->dma_index);
-    m3_remove_list(card, &(card->msrc_list), db->msrc_index);
-    db->in_lists = 0;
-}
-
-static void
-free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    if(db->rawbuf == NULL)
-        return;
-
-    DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db);
-
-    {
-        struct page *page, *pend;
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            ClearPageReserved(page);
-    }
-
-
-    pci_free_consistent(pci_dev, PAGE_SIZE << db->buforder,
-            db->rawbuf, db->handle);
-
-    db->rawbuf = NULL;
-    db->buforder = 0;
-    db->mapped = 0;
-    db->ready = 0;
-}
-
-static int m3_open(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *c;
-    struct m3_state *s = NULL;
-    int i;
-    unsigned char fmtm = ~0, fmts = 0;
-    unsigned long flags;
-
-    /*
-     *    Scan the cards and find the channel. We only
-     *    do this at open time so it is ok
-     */
-    for(c = devs ; c != NULL ; c = c->next) {
-
-        for(i=0;i<NR_DSPS;i++) {
-
-            if(c->channels[i].dev_audio < 0)
-                continue;
-            if((c->channels[i].dev_audio ^ minor) & ~0xf)
-                continue;
-
-            s = &c->channels[i];
-            break;
-        }
-    }
-        
-    if (!s)
-        return -ENODEV;
-        
-    VALIDATE_STATE(s);
-
-    file->private_data = s;
-
-    /* wait for device to become free */
-    mutex_lock(&s->open_mutex);
-    while (s->open_mode & file->f_mode) {
-        if (file->f_flags & O_NONBLOCK) {
-            mutex_unlock(&s->open_mutex);
-            return -EWOULDBLOCK;
-        }
-        mutex_unlock(&s->open_mutex);
-        interruptible_sleep_on(&s->open_wait);
-        if (signal_pending(current))
-            return -ERESTARTSYS;
-        mutex_lock(&s->open_mutex);
-    }
-    
-    spin_lock_irqsave(&c->lock, flags);
-
-    if (file->f_mode & FMODE_READ) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; 
-
-        s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-        set_adc_rate(s, 8000);
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-        s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-        set_dac_rate(s, 8000);
-    }
-    set_fmt(s, fmtm, fmts);
-    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-    mutex_unlock(&s->open_mutex);
-    spin_unlock_irqrestore(&c->lock, flags);
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release(struct inode *inode, struct file *file)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-       struct m3_card *card=s->card;
-    unsigned long flags;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        drain_dac(s, file->f_flags & O_NONBLOCK);
-
-    mutex_lock(&s->open_mutex);
-    spin_lock_irqsave(&card->lock, flags);
-
-    if (file->f_mode & FMODE_WRITE) {
-        stop_dac(s);
-        if(s->dma_dac.in_lists) {
-            m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index);
-            nuke_lists(s->card, &(s->dma_dac));
-        }
-    }
-    if (file->f_mode & FMODE_READ) {
-        stop_adc(s);
-        if(s->dma_adc.in_lists) {
-            m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index);
-            nuke_lists(s->card, &(s->dma_adc));
-        }
-    }
-        
-    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-    spin_unlock_irqrestore(&card->lock, flags);
-    mutex_unlock(&s->open_mutex);
-    wake_up(&s->open_wait);
-
-    return 0;
-}
-
-/*
- * Wait for the ac97 serial bus to be free.
- * return nonzero if the bus is still busy.
- */
-static int m3_ac97_wait(struct m3_card *card)
-{
-    int i = 10000;
-
-    while( (m3_inb(card, 0x30) & 1) && i--) ;
-
-    return i == 0;
-}
-
-static u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
-{
-    u16 ret = 0;
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy reading reg 0x%x\n",reg);
-        goto out;
-    }
-
-    m3_outb(card, 0x80 | (reg & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy finishing read reg 0x%x\n",reg);
-        goto out;
-    }
-
-    ret =  m3_inw(card, 0x32);
-    DPRINTK(DPCRAP,"reading 0x%04x from 0x%02x\n",ret, reg);
-
-out:
-    spin_unlock(&card->ac97_lock);
-    return ret;
-}
-
-static void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
-{
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy writing 0x%x to 0x%x\n",val, reg);
-        goto out;
-    }
-    DPRINTK(DPCRAP,"writing 0x%04x  to  0x%02x\n", val, reg);
-
-    m3_outw(card, val, 0x32);
-    m3_outb(card, reg & 0x7f, 0x30);
-out:
-    spin_unlock(&card->ac97_lock);
-}
-/* OSS /dev/mixer file operation methods */
-static int m3_open_mixdev(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *card = devs;
-
-    for (card = devs; card != NULL; card = card->next) {
-        if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor))
-                break;
-    }
-
-    if (!card) {
-        return -ENODEV;
-    }
-
-    file->private_data = card->ac97;
-
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release_mixdev(struct inode *inode, struct file *file)
-{
-    return 0;
-}
-
-static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
-                                    unsigned long arg)
-{
-    struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-    return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static struct file_operations m3_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = m3_ioctl_mixdev,
-       .open    = m3_open_mixdev,
-       .release = m3_release_mixdev,
-};
-
-static void remote_codec_config(int io, int isremote)
-{
-    isremote = isremote ? 1 : 0;
-
-    outw(  (inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
-            io + RING_BUS_CTRL_B);
-    outw(  (inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
-            io + SDO_OUT_DEST_CTRL);
-    outw(  (inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
-            io + SDO_IN_DEST_CTRL);
-}
-
-/* 
- * hack, returns non zero on err 
- */
-static int try_read_vendor(struct m3_card *card)
-{
-    u16 ret;
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    m3_outb(card, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    ret =  m3_inw(card, 0x32);
-
-    return (ret == 0) || (ret == 0xffff);
-}
-
-static void m3_codec_reset(struct m3_card *card, int busywait)
-{
-    u16 dir;
-    int delay1 = 0, delay2 = 0, i;
-    int io = card->iobase;
-
-    switch (card->card_type) {
-        /*
-         * the onboard codec on the allegro seems 
-         * to want to wait a very long time before
-         * coming back to life 
-         */
-        case ESS_ALLEGRO:
-            delay1 = 50;
-            delay2 = 800;
-        break;
-        case ESS_MAESTRO3:
-        case ESS_MAESTRO3HW:
-            delay1 = 20;
-            delay2 = 500;
-        break;
-    }
-
-    for(i = 0; i < 5; i ++) {
-        dir = inw(io + GPIO_DIRECTION);
-        dir |= 0x10; /* assuming pci bus master? */
-
-        remote_codec_config(io, 0);
-
-        outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
-        udelay(20);
-
-        outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
-        outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
-        outw(0, io + GPIO_DATA);
-        outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
-
-        if(busywait)  {
-            mdelay(delay1);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay1 * HZ) / 1000);
-        }
-
-        outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
-        udelay(5);
-        /* ok, bring back the ac-link */
-        outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
-        outw(~0, io + GPIO_MASK);
-
-        if(busywait) {
-            mdelay(delay2);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay2 * HZ) / 1000);
-        }
-        if(! try_read_vendor(card))
-            break;
-
-        delay1 += 10;
-        delay2 += 100;
-
-        DPRINTK(DPMOD, "retrying codec reset with delays of %d and %d ms\n",
-                delay1, delay2);
-    }
-
-#if 0
-    /* more gung-ho reset that doesn't
-     * seem to work anywhere :)
-     */
-    tmp = inw(io + RING_BUS_CTRL_A);
-    outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
-    mdelay(20);
-    outw(tmp, io + RING_BUS_CTRL_A);
-    mdelay(50);
-#endif
-}
-
-static int __devinit m3_codec_install(struct m3_card *card)
-{
-    struct ac97_codec *codec;
-
-    if ((codec = ac97_alloc_codec()) == NULL)
-        return -ENOMEM;
-
-    codec->private_data = card;
-    codec->codec_read = m3_ac97_read;
-    codec->codec_write = m3_ac97_write;
-    /* someday we should support secondary codecs.. */
-    codec->id = 0;
-
-    if (ac97_probe_codec(codec) == 0) {
-        printk(KERN_ERR PFX "codec probe failed\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) {
-        printk(KERN_ERR PFX "couldn't register mixer!\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    card->ac97 = codec;
-
-    return 0;
-}
-
-
-#define MINISRC_LPF_LEN 10
-static u16 minisrc_lpf[MINISRC_LPF_LEN] = {
-    0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
-    0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
-};
-static void m3_assp_init(struct m3_card *card)
-{
-    int i;
-
-    /* zero kernel data */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR + i, 0);
-
-    /* zero mixer data? */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR2 + i, 0);
-
-    /* init dma pointer */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_CURRENT_DMA, 
-            KDATA_DMA_XFER0);
-
-    /* write kernel into code memory.. */
-    for(i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                REV_B_CODE_MEMORY_BEGIN + i, 
-                assp_kernel_image[i]);
-    }
-
-    /*
-     * We only have this one client and we know that 0x400
-     * is free in our kernel's mem map, so lets just
-     * drop it there.  It seems that the minisrc doesn't
-     * need vectors, so we won't bother with them..
-     */
-    for(i = 0 ; i < sizeof(assp_minisrc_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                0x400 + i, 
-                assp_minisrc_image[i]);
-    }
-
-    /*
-     * write the coefficients for the low pass filter?
-     */
-    for(i = 0; i < MINISRC_LPF_LEN ; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-            0x400 + MINISRC_COEF_LOC + i,
-            minisrc_lpf[i]);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-        0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
-        0x8000);
-
-    /*
-     * the minisrc is the only thing on
-     * our task list..
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_TASK0, 
-            0x400);
-
-    /*
-     * init the mixer number..
-     */
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER,0);
-
-    /*
-     * EXTREME KERNEL MASTER VOLUME
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
-
-    card->mixer_list.mem_addr = KDATA_MIXER_XFER0;
-    card->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
-    card->adc1_list.mem_addr = KDATA_ADC1_XFER0;
-    card->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
-    card->dma_list.mem_addr = KDATA_DMA_XFER0;
-    card->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
-    card->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
-    card->msrc_list.max = MAX_INSTANCE_MINISRC;
-}
-
-static int setup_msrc(struct m3_card *card,
-        struct assp_instance *inst, int index)
-{
-    int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
-            MINISRC_IN_BUFFER_SIZE / 2 +
-            1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
-    int address, i;
-
-    /*
-     * the revb memory map has 0x1100 through 0x1c00
-     * free.  
-     */
-
-    /*
-     * align instance address to 256 bytes so that it's
-     * shifted list address is aligned.  
-     * list address = (mem address >> 1) >> 7;
-     */
-    data_bytes = (data_bytes + 255) & ~255;
-    address = 0x1100 + ((data_bytes/2) * index);
-
-    if((address + (data_bytes/2)) >= 0x1c00) {
-        printk(KERN_ERR PFX "no memory for %d bytes at ind %d (addr 0x%x)\n",
-                data_bytes, index, address);
-        return -1;
-    }
-
-    for(i = 0; i < data_bytes/2 ; i++) 
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                address + i, 0);
-
-    inst->code = 0x400;
-    inst->data = address;
-
-    return 0;
-}
-
-static int m3_assp_client_init(struct m3_state *s)
-{
-    setup_msrc(s->card, &(s->dac_inst), s->index * 2);
-    setup_msrc(s->card, &(s->adc_inst), (s->index * 2) + 1);
-
-    return 0;
-}
-
-static void m3_amp_enable(struct m3_card *card, int enable)
-{
-    /* 
-     * this works for the reference board, have to find
-     * out about others
-     *
-     * this needs more magic for 4 speaker, but..
-     */
-    int io = card->iobase;
-    u16 gpo, polarity_port, polarity;
-
-    if(!external_amp)
-        return;
-
-    if (gpio_pin >= 0  && gpio_pin <= 15) {
-        polarity_port = 0x1000 + (0x100 * gpio_pin);
-    } else {
-        switch (card->card_type) {
-            case ESS_ALLEGRO:
-                polarity_port = 0x1800;
-                break;
-            default:
-                polarity_port = 0x1100;
-                /* Panasonic toughbook CF72 has to be different... */
-                if(card->pcidev->subsystem_vendor == 0x10F7 && card->pcidev->subsystem_device == 0x833D)
-                       polarity_port = 0x1D00;
-                break;
-        }
-    }
-
-    gpo = (polarity_port >> 8) & 0x0F;
-    polarity = polarity_port >> 12;
-    if ( enable )
-        polarity = !polarity;
-    polarity = polarity << gpo;
-    gpo = 1 << gpo;
-
-    outw(~gpo , io + GPIO_MASK);
-
-    outw( inw(io + GPIO_DIRECTION) | gpo ,
-            io + GPIO_DIRECTION);
-
-    outw( (GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity) ,
-            io + GPIO_DATA);
-
-    outw(0xffff , io + GPIO_MASK);
-}
-
-static int
-maestro_config(struct m3_card *card) 
-{
-    struct pci_dev *pcidev = card->pcidev;
-    u32 n;
-    u8  t; /* makes as much sense as 'n', no? */
-
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= REDUCED_DEBOUNCE;
-    n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    outb(RESET_ASSP, card->iobase + ASSP_CONTROL_B);
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= ~INT_CLK_SELECT;
-    if(card->card_type >= ESS_MAESTRO3)  {
-        n &= ~INT_CLK_MULT_ENABLE; 
-        n |= INT_CLK_SRC_NOT_PCI;
-    }
-    n &=  ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    if(card->card_type <= ESS_ALLEGRO) {
-        pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
-        n |= IN_CLK_12MHZ_SELECT;
-        pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
-    }
-
-    t = inb(card->iobase + ASSP_CONTROL_A);
-    t &= ~( DSP_CLK_36MHZ_SELECT  | ASSP_CLK_49MHZ_SELECT);
-    t |= ASSP_CLK_49MHZ_SELECT;
-    t |= ASSP_0_WS_ENABLE; 
-    outb(t, card->iobase + ASSP_CONTROL_A);
-
-    outb(RUN_ASSP, card->iobase + ASSP_CONTROL_B); 
-
-    return 0;
-} 
-
-static void m3_enable_ints(struct m3_card *card)
-{
-    unsigned long io = card->iobase;
-
-    outw(ASSP_INT_ENABLE, io + HOST_INT_CTRL);
-    outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
-            io + ASSP_CONTROL_C);
-}
-
-static struct file_operations m3_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = m3_read,
-       .write   = m3_write,
-       .poll    = m3_poll,
-       .ioctl   = m3_ioctl,
-       .mmap    = m3_mmap,
-       .open    = m3_open,
-       .release = m3_release,
-};
-
-#ifdef CONFIG_PM
-static int alloc_dsp_suspendmem(struct m3_card *card)
-{
-    int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-
-    if( (card->suspend_mem = vmalloc(len)) == NULL)
-        return 1;
-
-    return 0;
-}
-
-#else
-#define alloc_dsp_suspendmem(args...) 0
-#endif
-
-/*
- * great day!  this function is ugly as hell.
- */
-static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-    u32 n;
-    int i;
-    struct m3_card *card = NULL;
-    int ret = 0;
-    int card_type = pci_id->driver_data;
-
-    DPRINTK(DPMOD, "in maestro_install\n");
-
-    if (pci_enable_device(pci_dev))
-        return -EIO;
-
-    if (pci_set_dma_mask(pci_dev, M3_PCI_DMA_MASK)) {
-        printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n");
-        return -ENODEV;
-    }
-        
-    pci_set_master(pci_dev);
-
-    if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
-        printk(KERN_WARNING PFX "out of memory\n");
-        return -ENOMEM;
-    }
-    memset(card, 0, sizeof(struct m3_card));
-    card->pcidev = pci_dev;
-    init_waitqueue_head(&card->suspend_queue);
-
-    if ( ! request_region(pci_resource_start(pci_dev, 0),
-                pci_resource_len (pci_dev, 0), M3_MODULE_NAME)) {
-
-        printk(KERN_WARNING PFX "unable to reserve I/O space.\n");
-        ret = -EBUSY;
-        goto out;
-    }
-
-    card->iobase = pci_resource_start(pci_dev, 0);
-
-    if(alloc_dsp_suspendmem(card)) {
-        printk(KERN_WARNING PFX "couldn't alloc %d bytes for saving dsp state on suspend\n",
-                REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-        ret = -ENOMEM;
-        goto out;
-    }
-
-    card->card_type = card_type;
-    card->irq = pci_dev->irq;
-    card->next = devs;
-    card->magic = M3_CARD_MAGIC;
-    spin_lock_init(&card->lock);
-    spin_lock_init(&card->ac97_lock);
-    devs = card;
-    for(i = 0; i<NR_DSPS; i++) {
-        struct m3_state *s = &(card->channels[i]);
-        s->dev_audio = -1;
-    }
-
-    printk(KERN_INFO PFX "Configuring ESS %s found at IO 0x%04X IRQ %d\n", 
-        card_names[card->card_type], card->iobase, card->irq);
-
-    pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-    printk(KERN_INFO PFX " subvendor id: 0x%08x\n",n); 
-
-    maestro_config(card);
-    m3_assp_halt(card);
-
-    m3_codec_reset(card, 0);
-
-    if(m3_codec_install(card))  {
-        ret = -EIO; 
-        goto out;
-    }
-
-    m3_assp_init(card);
-    m3_amp_enable(card, 1);
-    
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s=&card->channels[i];
-
-        s->index = i;
-
-        s->card = card;
-        init_waitqueue_head(&s->dma_adc.wait);
-        init_waitqueue_head(&s->dma_dac.wait);
-        init_waitqueue_head(&s->open_wait);
-        mutex_init(&(s->open_mutex));
-        s->magic = M3_STATE_MAGIC;
-
-        m3_assp_client_init(s);
-        
-        if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-            printk(KERN_WARNING PFX "initing a dsp device that is already in use?\n");
-        /* register devices */
-        if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) {
-            break;
-        }
-
-        if( allocate_dmabuf(card->pcidev, &(s->dma_adc)) ||
-                allocate_dmabuf(card->pcidev, &(s->dma_dac)))  { 
-            ret = -ENOMEM;
-            goto out;
-        }
-    }
-    
-    if(request_irq(card->irq, m3_interrupt, IRQF_SHARED, card_names[card->card_type], card)) {
-
-        printk(KERN_ERR PFX "unable to allocate irq %d,\n", card->irq);
-
-        ret = -EIO;
-        goto out;
-    }
-
-    pci_set_drvdata(pci_dev, card);
-    
-    m3_enable_ints(card);
-    m3_assp_continue(card);
-
-out:
-    if(ret) {
-        if(card->iobase)
-            release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-        vfree(card->suspend_mem);
-        if(card->ac97) {
-            unregister_sound_mixer(card->ac97->dev_mixer);
-            kfree(card->ac97);
-        }
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio != -1)
-                unregister_sound_dsp(s->dev_audio);
-        }
-        kfree(card);
-    }
-
-    return ret; 
-}
-
-static void m3_remove(struct pci_dev *pci_dev)
-{
-    struct m3_card *card;
-
-    unregister_reboot_notifier(&m3_reboot_nb);
-
-    while ((card = devs)) {
-        int i;
-        devs = devs->next;
-    
-        free_irq(card->irq, card);
-        unregister_sound_mixer(card->ac97->dev_mixer);
-        kfree(card->ac97);
-
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio < 0)
-                continue;
-
-            unregister_sound_dsp(s->dev_audio);
-            free_dmabuf(card->pcidev, &s->dma_adc);
-            free_dmabuf(card->pcidev, &s->dma_dac);
-        }
-
-        release_region(card->iobase, 256);
-        vfree(card->suspend_mem);
-        kfree(card);
-    }
-    devs = NULL;
-}
-
-/*
- * some bioses like the sound chip to be powered down
- * at shutdown.  We're just calling _suspend to
- * achieve that..
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-    struct m3_card *card;
-
-    DPRINTK(DPMOD, "notifier suspending all cards\n");
-
-    for(card = devs; card != NULL; card = card->next) {
-        if(!card->in_suspend)
-            m3_suspend(card->pcidev, PMSG_SUSPEND); /* XXX legal? */
-    }
-    return 0;
-}
-
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
-    unsigned long flags;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-    /* must be a better way.. */
-       spin_lock_irqsave(&card->lock, flags);
-
-    DPRINTK(DPMOD, "pm in dev %p\n",card);
-
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-
-        if(s->dev_audio == -1)
-            continue;
-
-        DPRINTK(DPMOD, "stop_adc/dac() device %d\n",i);
-        stop_dac(s);
-        stop_adc(s);
-    }
-
-    mdelay(10); /* give the assp a chance to idle.. */
-
-    m3_assp_halt(card);
-
-    if(card->suspend_mem) {
-        int index = 0;
-
-        DPRINTK(DPMOD, "saving code\n");
-        for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_CODE, i);
-        DPRINTK(DPMOD, "saving data\n");
-        for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_DATA, i);
-    }
-
-    DPRINTK(DPMOD, "powering down apci regs\n");
-    m3_outw(card, 0xffff, 0x54);
-    m3_outw(card, 0xffff, 0x56);
-
-    card->in_suspend = 1;
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    return 0;
-}
-
-static int m3_resume(struct pci_dev *pci_dev)
-{
-    unsigned long flags;
-    int index;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-       spin_lock_irqsave(&card->lock, flags);
-    card->in_suspend = 0;
-
-    DPRINTK(DPMOD, "resuming\n");
-
-    /* first lets just bring everything back. .*/
-
-    DPRINTK(DPMOD, "bringing power back on card 0x%p\n",card);
-    m3_outw(card, 0, 0x54);
-    m3_outw(card, 0, 0x56);
-
-    DPRINTK(DPMOD, "restoring pci configs and reseting codec\n");
-    maestro_config(card);
-    m3_assp_halt(card);
-    m3_codec_reset(card, 1);
-
-    DPRINTK(DPMOD, "restoring dsp code card\n");
-    index = 0;
-    for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, i, 
-            card->suspend_mem[index++]);
-    for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, i, 
-            card->suspend_mem[index++]);
-
-     /* tell the dma engine to restart itself */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-        KDATA_DMA_ACTIVE, 0);
-
-    DPRINTK(DPMOD, "resuming dsp\n");
-    m3_assp_continue(card);
-
-    DPRINTK(DPMOD, "enabling ints\n");
-    m3_enable_ints(card);
-
-    /* bring back the old school flavor */
-    for(i = 0; i < SOUND_MIXER_NRDEVICES ; i++) {
-        int state = card->ac97->mixer_state[i];
-        if (!supported_mixer(card->ac97, i)) 
-                continue;
-
-        card->ac97->write_mixer(card->ac97, i, 
-                state & 0xff, (state >> 8) & 0xff);
-    }
-
-    m3_amp_enable(card, 1);
-
-    /* 
-     * now we flip on the music 
-     */
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-        if(s->dev_audio == -1)
-            continue;
-        /*
-         * db->ready makes it so these guys can be
-         * called unconditionally..
-         */
-        DPRINTK(DPMOD, "turning on dacs ind %d\n",i);
-        start_dac(s);    
-        start_adc(s);    
-    }
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    /* 
-     * all right, we think things are ready, 
-     * wake up people who were using the device 
-     * when we suspended
-     */
-    wake_up(&card->suspend_queue);
-
-    return 0;
-}
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
-MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, int, 0);
-#endif
-module_param(external_amp, int, 0);
-module_param(gpio_pin, int, 0);
-
-static struct pci_driver m3_pci_driver = {
-       .name     = "ess_m3_audio",
-       .id_table = m3_id_table,
-       .probe    = m3_probe,
-       .remove   = m3_remove,
-       .suspend  = m3_suspend,
-       .resume   = m3_resume,
-};
-
-static int __init m3_init_module(void)
-{
-    printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n");
-
-    if (register_reboot_notifier(&m3_reboot_nb)) {
-        printk(KERN_WARNING PFX "reboot notifier registration failed\n");
-        return -ENODEV; /* ? */
-    }
-
-    if (pci_register_driver(&m3_pci_driver)) {
-        unregister_reboot_notifier(&m3_reboot_nb);
-        return -ENODEV;
-    }
-    return 0;
-}
-
-static void __exit m3_cleanup_module(void)
-{
-    pci_unregister_driver(&m3_pci_driver);
-}
-
-module_init(m3_init_module);
-module_exit(m3_cleanup_module);
-
-void check_suspend(struct m3_card *card)
-{
-    DECLARE_WAITQUEUE(wait, current);
-
-    if(!card->in_suspend) 
-        return;
-
-    card->in_suspend++;
-    add_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule();
-    remove_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_RUNNING);
-}
diff --git a/sound/oss/maestro3.h b/sound/oss/maestro3.h
deleted file mode 100644 (file)
index dde2986..0000000
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- *      ESS Technology allegro audio driver.
- *
- *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *      Hacked for the maestro3 driver by zab
- */
-
-// Allegro PCI configuration registers
-#define PCI_LEGACY_AUDIO_CTRL   0x40
-#define SOUND_BLASTER_ENABLE    0x00000001
-#define FM_SYNTHESIS_ENABLE     0x00000002
-#define GAME_PORT_ENABLE        0x00000004
-#define MPU401_IO_ENABLE        0x00000008
-#define MPU401_IRQ_ENABLE       0x00000010
-#define ALIAS_10BIT_IO          0x00000020
-#define SB_DMA_MASK             0x000000C0
-#define SB_DMA_0                0x00000040
-#define SB_DMA_1                0x00000040
-#define SB_DMA_R                0x00000080
-#define SB_DMA_3                0x000000C0
-#define SB_IRQ_MASK             0x00000700
-#define SB_IRQ_5                0x00000000
-#define SB_IRQ_7                0x00000100
-#define SB_IRQ_9                0x00000200
-#define SB_IRQ_10               0x00000300
-#define MIDI_IRQ_MASK           0x00003800
-#define SERIAL_IRQ_ENABLE       0x00004000
-#define DISABLE_LEGACY          0x00008000
-
-#define PCI_ALLEGRO_CONFIG      0x50
-#define SB_ADDR_240             0x00000004
-#define MPU_ADDR_MASK           0x00000018
-#define MPU_ADDR_330            0x00000000
-#define MPU_ADDR_300            0x00000008
-#define MPU_ADDR_320            0x00000010
-#define MPU_ADDR_340            0x00000018
-#define USE_PCI_TIMING          0x00000040
-#define POSTED_WRITE_ENABLE     0x00000080
-#define DMA_POLICY_MASK         0x00000700
-#define DMA_DDMA                0x00000000
-#define DMA_TDMA                0x00000100
-#define DMA_PCPCI               0x00000200
-#define DMA_WBDMA16             0x00000400
-#define DMA_WBDMA4              0x00000500
-#define DMA_WBDMA2              0x00000600
-#define DMA_WBDMA1              0x00000700
-#define DMA_SAFE_GUARD          0x00000800
-#define HI_PERF_GP_ENABLE       0x00001000
-#define PIC_SNOOP_MODE_0        0x00002000
-#define PIC_SNOOP_MODE_1        0x00004000
-#define SOUNDBLASTER_IRQ_MASK   0x00008000
-#define RING_IN_ENABLE          0x00010000
-#define SPDIF_TEST_MODE         0x00020000
-#define CLK_MULT_MODE_SELECT_2  0x00040000
-#define EEPROM_WRITE_ENABLE     0x00080000
-#define CODEC_DIR_IN            0x00100000
-#define HV_BUTTON_FROM_GD       0x00200000
-#define REDUCED_DEBOUNCE        0x00400000
-#define HV_CTRL_ENABLE          0x00800000
-#define SPDIF_ENABLE            0x01000000
-#define CLK_DIV_SELECT          0x06000000
-#define CLK_DIV_BY_48           0x00000000
-#define CLK_DIV_BY_49           0x02000000
-#define CLK_DIV_BY_50           0x04000000
-#define CLK_DIV_RESERVED        0x06000000
-#define PM_CTRL_ENABLE          0x08000000
-#define CLK_MULT_MODE_SELECT    0x30000000
-#define CLK_MULT_MODE_SHIFT     28
-#define CLK_MULT_MODE_0         0x00000000
-#define CLK_MULT_MODE_1         0x10000000
-#define CLK_MULT_MODE_2         0x20000000
-#define CLK_MULT_MODE_3         0x30000000
-#define INT_CLK_SELECT          0x40000000
-#define INT_CLK_MULT_RESET      0x80000000
-
-// M3
-#define INT_CLK_SRC_NOT_PCI     0x00100000
-#define INT_CLK_MULT_ENABLE     0x80000000
-
-#define PCI_ACPI_CONTROL        0x54
-#define PCI_ACPI_D0             0x00000000
-#define PCI_ACPI_D1             0xB4F70000
-#define PCI_ACPI_D2             0xB4F7B4F7
-
-#define PCI_USER_CONFIG         0x58
-#define EXT_PCI_MASTER_ENABLE   0x00000001
-#define SPDIF_OUT_SELECT        0x00000002
-#define TEST_PIN_DIR_CTRL       0x00000004
-#define AC97_CODEC_TEST         0x00000020
-#define TRI_STATE_BUFFER        0x00000080
-#define IN_CLK_12MHZ_SELECT     0x00000100
-#define MULTI_FUNC_DISABLE      0x00000200
-#define EXT_MASTER_PAIR_SEL     0x00000400
-#define PCI_MASTER_SUPPORT      0x00000800
-#define STOP_CLOCK_ENABLE       0x00001000
-#define EAPD_DRIVE_ENABLE       0x00002000
-#define REQ_TRI_STATE_ENABLE    0x00004000
-#define REQ_LOW_ENABLE          0x00008000
-#define MIDI_1_ENABLE           0x00010000
-#define MIDI_2_ENABLE           0x00020000
-#define SB_AUDIO_SYNC           0x00040000
-#define HV_CTRL_TEST            0x00100000
-#define SOUNDBLASTER_TEST       0x00400000
-
-#define PCI_USER_CONFIG_C       0x5C
-
-#define PCI_DDMA_CTRL           0x60
-#define DDMA_ENABLE             0x00000001
-
-
-// Allegro registers
-#define HOST_INT_CTRL           0x18
-#define SB_INT_ENABLE           0x0001
-#define MPU401_INT_ENABLE       0x0002
-#define ASSP_INT_ENABLE         0x0010
-#define RING_INT_ENABLE         0x0020
-#define HV_INT_ENABLE           0x0040
-#define CLKRUN_GEN_ENABLE       0x0100
-#define HV_CTRL_TO_PME          0x0400
-#define SOFTWARE_RESET_ENABLE   0x8000
-
-/*
- * should be using the above defines, probably.
- */
-#define REGB_ENABLE_RESET               0x01
-#define REGB_STOP_CLOCK                 0x10
-
-#define HOST_INT_STATUS         0x1A
-#define SB_INT_PENDING          0x01
-#define MPU401_INT_PENDING      0x02
-#define ASSP_INT_PENDING        0x10
-#define RING_INT_PENDING        0x20
-#define HV_INT_PENDING          0x40
-
-#define HARDWARE_VOL_CTRL       0x1B
-#define SHADOW_MIX_REG_VOICE    0x1C
-#define HW_VOL_COUNTER_VOICE    0x1D
-#define SHADOW_MIX_REG_MASTER   0x1E
-#define HW_VOL_COUNTER_MASTER   0x1F
-
-#define CODEC_COMMAND           0x30
-#define CODEC_READ_B            0x80
-
-#define CODEC_STATUS            0x30
-#define CODEC_BUSY_B            0x01
-
-#define CODEC_DATA              0x32
-
-#define RING_BUS_CTRL_A         0x36
-#define RAC_PME_ENABLE          0x0100
-#define RAC_SDFS_ENABLE         0x0200
-#define LAC_PME_ENABLE          0x0400
-#define LAC_SDFS_ENABLE         0x0800
-#define SERIAL_AC_LINK_ENABLE   0x1000
-#define IO_SRAM_ENABLE          0x2000
-#define IIS_INPUT_ENABLE        0x8000
-
-#define RING_BUS_CTRL_B         0x38
-#define SECOND_CODEC_ID_MASK    0x0003
-#define SPDIF_FUNC_ENABLE       0x0010
-#define SECOND_AC_ENABLE        0x0020
-#define SB_MODULE_INTF_ENABLE   0x0040
-#define SSPE_ENABLE             0x0040
-#define M3I_DOCK_ENABLE         0x0080
-
-#define SDO_OUT_DEST_CTRL       0x3A
-#define COMMAND_ADDR_OUT        0x0003
-#define PCM_LR_OUT_LOCAL        0x0000
-#define PCM_LR_OUT_REMOTE       0x0004
-#define PCM_LR_OUT_MUTE         0x0008
-#define PCM_LR_OUT_BOTH         0x000C
-#define LINE1_DAC_OUT_LOCAL     0x0000
-#define LINE1_DAC_OUT_REMOTE    0x0010
-#define LINE1_DAC_OUT_MUTE      0x0020
-#define LINE1_DAC_OUT_BOTH      0x0030
-#define PCM_CLS_OUT_LOCAL       0x0000
-#define PCM_CLS_OUT_REMOTE      0x0040
-#define PCM_CLS_OUT_MUTE        0x0080
-#define PCM_CLS_OUT_BOTH        0x00C0
-#define PCM_RLF_OUT_LOCAL       0x0000
-#define PCM_RLF_OUT_REMOTE      0x0100
-#define PCM_RLF_OUT_MUTE        0x0200
-#define PCM_RLF_OUT_BOTH        0x0300
-#define LINE2_DAC_OUT_LOCAL     0x0000
-#define LINE2_DAC_OUT_REMOTE    0x0400
-#define LINE2_DAC_OUT_MUTE      0x0800
-#define LINE2_DAC_OUT_BOTH      0x0C00
-#define HANDSET_OUT_LOCAL       0x0000
-#define HANDSET_OUT_REMOTE      0x1000
-#define HANDSET_OUT_MUTE        0x2000
-#define HANDSET_OUT_BOTH        0x3000
-#define IO_CTRL_OUT_LOCAL       0x0000
-#define IO_CTRL_OUT_REMOTE      0x4000
-#define IO_CTRL_OUT_MUTE        0x8000
-#define IO_CTRL_OUT_BOTH        0xC000
-
-#define SDO_IN_DEST_CTRL        0x3C
-#define STATUS_ADDR_IN          0x0003
-#define PCM_LR_IN_LOCAL         0x0000
-#define PCM_LR_IN_REMOTE        0x0004
-#define PCM_LR_RESERVED         0x0008
-#define PCM_LR_IN_BOTH          0x000C
-#define LINE1_ADC_IN_LOCAL      0x0000
-#define LINE1_ADC_IN_REMOTE     0x0010
-#define LINE1_ADC_IN_MUTE       0x0020
-#define MIC_ADC_IN_LOCAL        0x0000
-#define MIC_ADC_IN_REMOTE       0x0040
-#define MIC_ADC_IN_MUTE         0x0080
-#define LINE2_DAC_IN_LOCAL      0x0000
-#define LINE2_DAC_IN_REMOTE     0x0400
-#define LINE2_DAC_IN_MUTE       0x0800
-#define HANDSET_IN_LOCAL        0x0000
-#define HANDSET_IN_REMOTE       0x1000
-#define HANDSET_IN_MUTE         0x2000
-#define IO_STATUS_IN_LOCAL      0x0000
-#define IO_STATUS_IN_REMOTE     0x4000
-
-#define SPDIF_IN_CTRL           0x3E
-#define SPDIF_IN_ENABLE         0x0001
-
-#define GPIO_DATA               0x60
-#define GPIO_DATA_MASK          0x0FFF
-#define GPIO_HV_STATUS          0x3000
-#define GPIO_PME_STATUS         0x4000
-
-#define GPIO_MASK               0x64
-#define GPIO_DIRECTION          0x68
-#define GPO_PRIMARY_AC97        0x0001
-#define GPI_LINEOUT_SENSE       0x0004
-#define GPO_SECONDARY_AC97      0x0008
-#define GPI_VOL_DOWN            0x0010
-#define GPI_VOL_UP              0x0020
-#define GPI_IIS_CLK             0x0040
-#define GPI_IIS_LRCLK           0x0080
-#define GPI_IIS_DATA            0x0100
-#define GPI_DOCKING_STATUS      0x0100
-#define GPI_HEADPHONE_SENSE     0x0200
-#define GPO_EXT_AMP_SHUTDOWN    0x1000
-
-// M3
-#define GPO_M3_EXT_AMP_SHUTDN   0x0002
-
-#define ASSP_INDEX_PORT         0x80
-#define ASSP_MEMORY_PORT        0x82
-#define ASSP_DATA_PORT          0x84
-
-#define MPU401_DATA_PORT        0x98
-#define MPU401_STATUS_PORT      0x99
-
-#define CLK_MULT_DATA_PORT      0x9C
-
-#define ASSP_CONTROL_A          0xA2
-#define ASSP_0_WS_ENABLE        0x01
-#define ASSP_CTRL_A_RESERVED1   0x02
-#define ASSP_CTRL_A_RESERVED2   0x04
-#define ASSP_CLK_49MHZ_SELECT   0x08
-#define FAST_PLU_ENABLE         0x10
-#define ASSP_CTRL_A_RESERVED3   0x20
-#define DSP_CLK_36MHZ_SELECT    0x40
-
-#define ASSP_CONTROL_B          0xA4
-#define RESET_ASSP              0x00
-#define RUN_ASSP                0x01
-#define ENABLE_ASSP_CLOCK       0x00
-#define STOP_ASSP_CLOCK         0x10
-#define RESET_TOGGLE            0x40
-
-#define ASSP_CONTROL_C          0xA6
-#define ASSP_HOST_INT_ENABLE    0x01
-#define FM_ADDR_REMAP_DISABLE   0x02
-#define HOST_WRITE_PORT_ENABLE  0x08
-
-#define ASSP_HOST_INT_STATUS    0xAC
-#define DSP2HOST_REQ_PIORECORD  0x01
-#define DSP2HOST_REQ_I2SRATE    0x02
-#define DSP2HOST_REQ_TIMER      0x04
-
-// AC97 registers
-// XXX fix this crap up
-/*#define AC97_RESET              0x00*/
-
-#define AC97_VOL_MUTE_B         0x8000
-#define AC97_VOL_M              0x1F
-#define AC97_LEFT_VOL_S         8
-
-#define AC97_MASTER_VOL         0x02
-#define AC97_LINE_LEVEL_VOL     0x04
-#define AC97_MASTER_MONO_VOL    0x06
-#define AC97_PC_BEEP_VOL        0x0A
-#define AC97_PC_BEEP_VOL_M      0x0F
-#define AC97_SROUND_MASTER_VOL  0x38
-#define AC97_PC_BEEP_VOL_S      1
-
-/*#define AC97_PHONE_VOL          0x0C
-#define AC97_MIC_VOL            0x0E*/
-#define AC97_MIC_20DB_ENABLE    0x40
-
-/*#define AC97_LINEIN_VOL         0x10
-#define AC97_CD_VOL             0x12
-#define AC97_VIDEO_VOL          0x14
-#define AC97_AUX_VOL            0x16*/
-#define AC97_PCM_OUT_VOL        0x18
-/*#define AC97_RECORD_SELECT      0x1A*/
-#define AC97_RECORD_MIC         0x00
-#define AC97_RECORD_CD          0x01
-#define AC97_RECORD_VIDEO       0x02
-#define AC97_RECORD_AUX         0x03
-#define AC97_RECORD_MONO_MUX    0x02
-#define AC97_RECORD_DIGITAL     0x03
-#define AC97_RECORD_LINE        0x04
-#define AC97_RECORD_STEREO      0x05
-#define AC97_RECORD_MONO        0x06
-#define AC97_RECORD_PHONE       0x07
-
-/*#define AC97_RECORD_GAIN        0x1C*/
-#define AC97_RECORD_VOL_M       0x0F
-
-/*#define AC97_GENERAL_PURPOSE    0x20*/
-#define AC97_POWER_DOWN_CTRL    0x26
-#define AC97_ADC_READY          0x0001
-#define AC97_DAC_READY          0x0002
-#define AC97_ANALOG_READY       0x0004
-#define AC97_VREF_ON            0x0008
-#define AC97_PR0                0x0100
-#define AC97_PR1                0x0200
-#define AC97_PR2                0x0400
-#define AC97_PR3                0x0800
-#define AC97_PR4                0x1000
-
-#define AC97_RESERVED1          0x28
-
-#define AC97_VENDOR_TEST        0x5A
-
-#define AC97_CLOCK_DELAY        0x5C
-#define AC97_LINEOUT_MUX_SEL    0x0001
-#define AC97_MONO_MUX_SEL       0x0002
-#define AC97_CLOCK_DELAY_SEL    0x1F
-#define AC97_DAC_CDS_SHIFT      6
-#define AC97_ADC_CDS_SHIFT      11
-
-#define AC97_MULTI_CHANNEL_SEL  0x74
-
-/*#define AC97_VENDOR_ID1         0x7C
-#define AC97_VENDOR_ID2         0x7E*/
-
-/*
- * ASSP control regs
- */
-#define DSP_PORT_TIMER_COUNT    0x06
-
-#define DSP_PORT_MEMORY_INDEX   0x80
-
-#define DSP_PORT_MEMORY_TYPE    0x82
-#define MEMTYPE_INTERNAL_CODE   0x0002
-#define MEMTYPE_INTERNAL_DATA   0x0003
-#define MEMTYPE_MASK            0x0003
-
-#define DSP_PORT_MEMORY_DATA    0x84
-
-#define DSP_PORT_CONTROL_REG_A  0xA2
-#define DSP_PORT_CONTROL_REG_B  0xA4
-#define DSP_PORT_CONTROL_REG_C  0xA6
-
-#define REV_A_CODE_MEMORY_BEGIN         0x0000
-#define REV_A_CODE_MEMORY_END           0x0FFF
-#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
-
-#define REV_B_CODE_MEMORY_BEGIN         0x0000
-#define REV_B_CODE_MEMORY_END           0x0BFF
-#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
-
-#define REV_A_DATA_MEMORY_BEGIN         0x1000
-#define REV_A_DATA_MEMORY_END           0x2FFF
-#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
-
-#define REV_B_DATA_MEMORY_BEGIN         0x1000
-#define REV_B_DATA_MEMORY_END           0x2BFF
-#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
-
-
-#define NUM_UNITS_KERNEL_CODE          16
-#define NUM_UNITS_KERNEL_DATA           2
-
-#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
-#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
-
-/*
- * Kernel data layout
- */
-
-#define DP_SHIFT_COUNT                  7
-
-#define KDATA_BASE_ADDR                 0x1000
-#define KDATA_BASE_ADDR2                0x1080
-
-#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
-#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
-#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
-#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
-#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
-#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
-#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
-#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
-#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
-
-#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
-#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
-
-#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
-#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
-#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
-#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
-#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
-#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
-#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
-#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
-#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
-#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
-
-#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
-#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
-
-#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
-#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
-
-#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
-#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
-
-#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
-#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
-#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
-
-#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
-#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
-#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
-#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
-#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
-
-#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
-#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
-#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
-
-#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
-#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
-#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
-
-#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
-#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
-#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
-#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
-#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
-#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
-#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
-#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
-#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
-#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
-
-#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
-#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
-#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
-
-#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
-#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
-
-#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
-#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
-#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
-
-#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
-#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
-#define KDATA_ADC1_LEFT_VOLUME                 (KDATA_BASE_ADDR + 0x003D)
-#define KDATA_ADC1_RIGHT_VOLUME                (KDATA_BASE_ADDR + 0x003E)
-#define KDATA_ADC1_LEFT_SUR_VOL                        (KDATA_BASE_ADDR + 0x003F)
-#define KDATA_ADC1_RIGHT_SUR_VOL               (KDATA_BASE_ADDR + 0x0040)
-
-#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
-#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
-#define KDATA_ADC2_LEFT_VOLUME                 (KDATA_BASE_ADDR + 0x0043)
-#define KDATA_ADC2_RIGHT_VOLUME                        (KDATA_BASE_ADDR + 0x0044)
-#define KDATA_ADC2_LEFT_SUR_VOL                        (KDATA_BASE_ADDR + 0x0045)
-#define KDATA_ADC2_RIGHT_SUR_VOL               (KDATA_BASE_ADDR + 0x0046)
-
-#define KDATA_CD_XFER0                                 (KDATA_BASE_ADDR + 0x0047)                                      
-#define KDATA_CD_XFER_ENDMARK                  (KDATA_BASE_ADDR + 0x0048)
-#define KDATA_CD_LEFT_VOLUME                   (KDATA_BASE_ADDR + 0x0049)
-#define KDATA_CD_RIGHT_VOLUME                  (KDATA_BASE_ADDR + 0x004A)
-#define KDATA_CD_LEFT_SUR_VOL                  (KDATA_BASE_ADDR + 0x004B)
-#define KDATA_CD_RIGHT_SUR_VOL                 (KDATA_BASE_ADDR + 0x004C)
-
-#define KDATA_MIC_XFER0                                        (KDATA_BASE_ADDR + 0x004D)
-#define KDATA_MIC_XFER_ENDMARK                 (KDATA_BASE_ADDR + 0x004E)
-#define KDATA_MIC_VOLUME                               (KDATA_BASE_ADDR + 0x004F)
-#define KDATA_MIC_SUR_VOL                              (KDATA_BASE_ADDR + 0x0050)
-
-#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
-#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
-
-#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
-#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
-
-#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
-#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
-#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
-#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
-#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
-
-#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
-#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
-
-#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
-#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
-#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
-
-#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
-#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
-
-#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
-
-#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
-#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
-#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
-#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
-#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
-#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
-#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
-#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
-#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
-#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
-#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
-#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
-
-#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
-#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
-#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
-#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
-
-#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
-#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
-
-#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
-#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
-#define KDATA_CD_REQUEST                               (KDATA_BASE_ADDR + 0x0076)
-#define KDATA_MIC_REQUEST                              (KDATA_BASE_ADDR + 0x0077)
-
-#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
-#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
-#define KDATA_CD_MIXER_REQUEST                 (KDATA_BASE_ADDR + 0x007A)
-#define KDATA_MIC_MIXER_REQUEST                        (KDATA_BASE_ADDR + 0x007B)
-#define KDATA_MIC_SYNC_COUNTER                 (KDATA_BASE_ADDR + 0x007C)
-
-/*
- * second 'segment' (?) reserved for mixer
- * buffers..
- */
-
-#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
-#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
-#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
-#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
-#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
-#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
-#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
-#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
-#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
-#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
-#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
-#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
-#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
-#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
-#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
-#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
-
-#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
-#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
-#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
-#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
-#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
-#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
-#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
-#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
-#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
-#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
-#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
-
-#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
-#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
-#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
-#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
-#define KDATA_DAC_LEFT_VOLUME          (KDATA_BASE_ADDR2 + 0x001F)
-#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
-
-#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
-#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
-#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
-#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
-
-/*
- * client data area offsets
- */
-#define CDATA_INSTANCE_READY            0x00
-
-#define CDATA_HOST_SRC_ADDRL            0x01
-#define CDATA_HOST_SRC_ADDRH            0x02
-#define CDATA_HOST_SRC_END_PLUS_1L      0x03
-#define CDATA_HOST_SRC_END_PLUS_1H      0x04
-#define CDATA_HOST_SRC_CURRENTL         0x05
-#define CDATA_HOST_SRC_CURRENTH         0x06
-
-#define CDATA_IN_BUF_CONNECT            0x07
-#define CDATA_OUT_BUF_CONNECT           0x08
-
-#define CDATA_IN_BUF_BEGIN              0x09
-#define CDATA_IN_BUF_END_PLUS_1         0x0A
-#define CDATA_IN_BUF_HEAD               0x0B
-#define CDATA_IN_BUF_TAIL               0x0C
-#define CDATA_OUT_BUF_BEGIN             0x0D
-#define CDATA_OUT_BUF_END_PLUS_1        0x0E
-#define CDATA_OUT_BUF_HEAD              0x0F
-#define CDATA_OUT_BUF_TAIL              0x10
-
-#define CDATA_DMA_CONTROL               0x11
-#define CDATA_RESERVED                  0x12
-
-#define CDATA_FREQUENCY                 0x13
-#define CDATA_LEFT_VOLUME               0x14
-#define CDATA_RIGHT_VOLUME              0x15
-#define CDATA_LEFT_SUR_VOL              0x16
-#define CDATA_RIGHT_SUR_VOL             0x17
-
-#define CDATA_HEADER_LEN                0x18
-
-#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
-#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
-#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
-#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
-#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
-#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
-#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
-#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
-
-#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
-#define MINISRC_BIQUAD_STAGE    2
-#define MINISRC_COEF_LOC          0X175
-
-#define DMACONTROL_BLOCK_MASK           0x000F
-#define  DMAC_BLOCK0_SELECTOR           0x0000
-#define  DMAC_BLOCK1_SELECTOR           0x0001
-#define  DMAC_BLOCK2_SELECTOR           0x0002
-#define  DMAC_BLOCK3_SELECTOR           0x0003
-#define  DMAC_BLOCK4_SELECTOR           0x0004
-#define  DMAC_BLOCK5_SELECTOR           0x0005
-#define  DMAC_BLOCK6_SELECTOR           0x0006
-#define  DMAC_BLOCK7_SELECTOR           0x0007
-#define  DMAC_BLOCK8_SELECTOR           0x0008
-#define  DMAC_BLOCK9_SELECTOR           0x0009
-#define  DMAC_BLOCKA_SELECTOR           0x000A
-#define  DMAC_BLOCKB_SELECTOR           0x000B
-#define  DMAC_BLOCKC_SELECTOR           0x000C
-#define  DMAC_BLOCKD_SELECTOR           0x000D
-#define  DMAC_BLOCKE_SELECTOR           0x000E
-#define  DMAC_BLOCKF_SELECTOR           0x000F
-#define DMACONTROL_PAGE_MASK            0x00F0
-#define  DMAC_PAGE0_SELECTOR            0x0030
-#define  DMAC_PAGE1_SELECTOR            0x0020
-#define  DMAC_PAGE2_SELECTOR            0x0010
-#define  DMAC_PAGE3_SELECTOR            0x0000
-#define DMACONTROL_AUTOREPEAT           0x1000
-#define DMACONTROL_STOPPED              0x2000
-#define DMACONTROL_DIRECTION            0x0100
-
-
-/*
- * DSP Code images
- */
-
-static u16 assp_kernel_image[] = {
-    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
-    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, 
-    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, 
-    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, 
-    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, 
-    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, 
-    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, 
-    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, 
-    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, 
-    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, 
-    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, 
-    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, 
-    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, 
-    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, 
-    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, 
-    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, 
-    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, 
-    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, 
-    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, 
-    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, 
-    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, 
-    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, 
-    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, 
-    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, 
-    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, 
-    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, 
-    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, 
-    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, 
-    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, 
-    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, 
-    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 
-    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, 
-    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, 
-    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, 
-    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, 
-    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 
-    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, 
-    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, 
-    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, 
-    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, 
-    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, 
-    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 
-    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, 
-    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, 
-    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, 
-    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 
-    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, 
-    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, 
-    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, 
-    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, 
-    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, 
-    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, 
-    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, 
-    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 
-    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, 
-    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 
-    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, 
-    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, 
-    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, 
-    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, 
-    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, 
-    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, 
-    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, 
-    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, 
-    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, 
-    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, 
-    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, 
-    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, 
-    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, 
-    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, 
-    0xBE3A, 
-};
-
-/*
- * Mini sample rate converter code image
- * that is to be loaded at 0x400 on the DSP.
- */
-static u16 assp_minisrc_image[] = {
-
-    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
-    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
-    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, 
-    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, 
-    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, 
-    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, 
-    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, 
-    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, 
-    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, 
-    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, 
-    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, 
-    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, 
-    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, 
-    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, 
-    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, 
-    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, 
-    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, 
-    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, 
-    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, 
-    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, 
-    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, 
-    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, 
-    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, 
-    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, 
-    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, 
-    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, 
-    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, 
-    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, 
-    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, 
-    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, 
-    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, 
-    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-};
-
diff --git a/sound/oss/maui.c b/sound/oss/maui.c
deleted file mode 100644 (file)
index 05cf194..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * sound/maui.c
- *
- * The low level driver for Turtle Beach Maui and Tropez.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *     Changes:
- *             Alan Cox                General clean up, use kernel IRQ 
- *                                     system
- *             Christoph Hellwig       Adapted to module_init/module_exit
- *             Bartlomiej Zolnierkiewicz
- *                                     Added __init to download_code()
- *
- *     Status:
- *             Andrew J. Kroll         Tested 06/01/1999 with:
- *                                     * OSWF.MOT File Version: 1.15
- *                                     * OSWF.MOT File Dated: 09/12/94
- *                                     * Older versions will cause problems.
- */
-
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include "sound_config.h"
-#include "sound_firmware.h"
-
-#include "mpu401.h"
-
-static int      maui_base = 0x330;
-
-static volatile int irq_ok;
-static int     *maui_osp;
-
-#define HOST_DATA_PORT (maui_base + 2)
-#define HOST_STAT_PORT (maui_base + 3)
-#define HOST_CTRL_PORT (maui_base + 3)
-
-#define STAT_TX_INTR   0x40
-#define STAT_TX_AVAIL  0x20
-#define STAT_TX_IENA   0x10
-#define STAT_RX_INTR   0x04
-#define STAT_RX_AVAIL  0x02
-#define STAT_RX_IENA   0x01
-
-static int      (*orig_load_patch)(int dev, int format, const char __user *addr,
-                             int offs, int count, int pmgr_flag) = NULL;
-
-#include "maui_boot.h"
-
-static int maui_wait(int mask)
-{
-       int i;
-
-       /*
-        * Perform a short initial wait without sleeping
-        */
-
-       for (i = 0; i < 100; i++)
-               if (inb(HOST_STAT_PORT) & mask)
-                       return 1;
-
-       /*
-        * Wait up to 15 seconds with sleeping
-        */
-
-       for (i = 0; i < 150; i++) {
-               if (inb(HOST_STAT_PORT) & mask)
-                       return 1;
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(HZ / 10);
-               if (signal_pending(current))
-                       return 0;
-       }
-       return 0;
-}
-
-static int maui_read(void)
-{
-       if (maui_wait(STAT_RX_AVAIL))
-               return inb(HOST_DATA_PORT);
-       return -1;
-}
-
-static int maui_write(unsigned char data)
-{
-       if (maui_wait(STAT_TX_AVAIL)) {
-               outb((data), HOST_DATA_PORT);
-               return 1;
-       }
-       printk(KERN_WARNING "Maui: Write timeout\n");
-       return 0;
-}
-
-static irqreturn_t mauiintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       irq_ok = 1;
-       return IRQ_HANDLED;
-}
-
-static int __init download_code(void)
-{
-       int i, lines = 0;
-       int eol_seen = 0, done = 0;
-       int skip = 1;
-
-       printk(KERN_INFO "Code download (%d bytes): ", maui_osLen);
-
-       for (i = 0; i < maui_osLen; i++) {
-               if (maui_os[i] != '\r') {
-                       if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n'))) {
-                               skip = 0;
-
-                               if (maui_os[i] == '\n')
-                                       eol_seen = skip = 1;
-                               else if (maui_os[i] == 'S') {
-                                       if (maui_os[i + 1] == '8')
-                                               done = 1;
-                                       if (!maui_write(0xF1))
-                                               goto failure;
-                                       if (!maui_write('S'))
-                                               goto failure;
-                               } else {
-                                       if (!maui_write(maui_os[i]))
-                                               goto failure;
-                               }
-
-                               if (eol_seen) {
-                                       int c = 0;
-                                       int n;
-
-                                       eol_seen = 0;
-
-                                       for (n = 0; n < 2; n++) {
-                                               if (maui_wait(STAT_RX_AVAIL)) {
-                                                       c = inb(HOST_DATA_PORT);
-                                                       break;
-                                               }
-                                       }
-                                       if (c != 0x80) {
-                                               printk("Download not acknowledged\n");
-                                               return 0;
-                                       }
-                                       else if (!(lines++ % 10))
-                                               printk(".");
-
-                                       if (done) {
-                                               printk("\n");
-                                               printk(KERN_INFO "Download complete\n");
-                                               return 1;
-                                       }
-                               }
-                       }
-               }
-       }
-
-failure:
-       printk("\n");
-       printk(KERN_ERR "Download failed!!!\n");
-       return 0;
-}
-
-static int __init maui_init(int irq)
-{
-       unsigned char bits;
-
-       switch (irq) {
-               case 9:
-                       bits = 0x00;
-                       break;
-               case 5:
-                       bits = 0x08;
-                       break;
-               case 12:
-                       bits = 0x10;
-                       break;
-               case 15:
-                       bits = 0x18;
-                       break;
-
-               default:
-                       printk(KERN_ERR "Maui: Invalid IRQ %d\n", irq);
-                       return 0;
-       }
-       outb((0x00), HOST_CTRL_PORT);   /* Reset */
-       outb((bits), HOST_DATA_PORT);   /* Set the IRQ bits */
-       outb((bits | 0x80), HOST_DATA_PORT);    /* Set the IRQ bits again? */
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-       outb((0xD0), HOST_CTRL_PORT);   /* Cause interrupt */
-
-#ifdef CONFIG_SMP
-       {
-               int i;
-               for (i = 0; i < 1000000 && !irq_ok; i++)
-                       ;
-               if (!irq_ok)
-                       return 0;
-       }
-#endif
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-
-       printk(KERN_INFO "Turtle Beach Maui initialization\n");
-
-       if (!download_code())
-               return 0;
-
-       outb((0xE0), HOST_CTRL_PORT);   /* Normal operation */
-
-       /* Select mpu401 mode */
-
-       maui_write(0xf0);
-       maui_write(1);
-       if (maui_read() != 0x80) {
-               maui_write(0xf0);
-               maui_write(1);
-               if (maui_read() != 0x80)
-                       printk(KERN_ERR "Maui didn't acknowledge set HW mode command\n");
-       }
-       printk(KERN_INFO "Maui initialized OK\n");
-       return 1;
-}
-
-static int maui_short_wait(int mask) {
-       int i;
-
-       for (i = 0; i < 1000; i++) {
-               if (inb(HOST_STAT_PORT) & mask) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int maui_load_patch(int dev, int format, const char __user *addr,
-               int offs, int count, int pmgr_flag)
-{
-
-       struct sysex_info header;
-       unsigned long left, src_offs;
-       int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
-       int i;
-
-       if (format == SYSEX_PATCH)      /* Handled by midi_synth.c */
-               return orig_load_patch(dev, format, addr, offs, count, pmgr_flag);
-
-       if (format != MAUI_PATCH)
-       {
-                 printk(KERN_WARNING "Maui: Unknown patch format\n");
-       }
-       if (count < hdr_size) {
-/*               printk("Maui error: Patch header too short\n");*/
-                 return -EINVAL;
-       }
-       count -= hdr_size;
-
-       /*
-        * Copy the header from user space but ignore the first bytes which have
-        * been transferred already.
-        */
-
-       if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
-               return -EFAULT;
-
-       if (count < header.len) {
-                 printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
-                 header.len = count;
-       }
-       left = header.len;
-       src_offs = 0;
-
-       for (i = 0; i < left; i++) {
-               unsigned char   data;
-
-               if(get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i])))
-                       return -EFAULT;
-               if (i == 0 && !(data & 0x80))
-                       return -EINVAL;
-
-               if (maui_write(data) == -1)
-                       return -EIO;
-       }
-
-       if ((i = maui_read()) != 0x80) {
-               if (i != -1)
-                       printk("Maui: Error status %02x\n", i);
-               return -EIO;
-       }
-       return 0;
-}
-
-static int __init probe_maui(struct address_info *hw_config)
-{
-       struct resource *ports;
-       int this_dev;
-       int i;
-       int tmp1, tmp2, ret;
-
-       ports = request_region(hw_config->io_base, 2, "mpu401");
-       if (!ports)
-               return 0;
-
-       if (!request_region(hw_config->io_base + 2, 6, "Maui"))
-               goto out;
-
-       maui_base = hw_config->io_base;
-       maui_osp = hw_config->osp;
-
-       if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0)
-               goto out2;
-
-       /*
-        * Initialize the processor if necessary
-        */
-
-       if (maui_osLen > 0) {
-               if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
-                       !maui_write(0x9F) ||    /* Report firmware version */
-                       !maui_short_wait(STAT_RX_AVAIL) ||
-                       maui_read() == -1 || maui_read() == -1)
-                       if (!maui_init(hw_config->irq))
-                               goto out3;
-       }
-       if (!maui_write(0xCF))  /* Report hardware version */ {
-               printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-               goto out3;
-       }
-       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
-               printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-               goto out3;
-       }
-       if (tmp1 == 0xff || tmp2 == 0xff)
-               goto out3;
-       printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
-
-       if (!maui_write(0x9F))  /* Report firmware version */
-               goto out3;
-       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
-               goto out3;
-
-       printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
-
-       if (!maui_write(0x85))  /* Report free DRAM */
-               goto out3;
-       tmp1 = 0;
-       for (i = 0; i < 4; i++) {
-               tmp1 |= maui_read() << (7 * i);
-       }
-       printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
-
-       for (i = 0; i < 1000; i++)
-               if (probe_mpu401(hw_config, ports))
-                       break;
-
-       ret = probe_mpu401(hw_config, ports);
-       if (!ret)
-               goto out3;
-
-       conf_printf("Maui", hw_config);
-
-       hw_config->irq *= -1;
-       hw_config->name = "Maui";
-       attach_mpu401(hw_config, THIS_MODULE);
-
-       if (hw_config->slots[1] != -1)  /* The MPU401 driver installed itself */ {
-               struct synth_operations *synth;
-
-               this_dev = hw_config->slots[1];
-
-               /*
-                * Intercept patch loading calls so that they can be handled
-                * by the Maui driver.
-                */
-
-               synth = midi_devs[this_dev]->converter;
-               if (synth != NULL) {
-                       synth->id = "MAUI";
-                       orig_load_patch = synth->load_patch;
-                       synth->load_patch = &maui_load_patch;
-               } else
-                       printk(KERN_ERR "Maui: Can't install patch loader\n");
-       }
-       return 1;
-
-out3:
-       free_irq(hw_config->irq, NULL);
-out2:
-       release_region(hw_config->io_base + 2, 6);
-out:
-       release_region(hw_config->io_base, 2);
-       return 0;
-}
-
-static void __exit unload_maui(struct address_info *hw_config)
-{
-       int irq = hw_config->irq;
-       release_region(hw_config->io_base + 2, 6);
-       unload_mpu401(hw_config);
-
-       if (irq < 0)
-               irq = -irq;
-       if (irq > 0)
-               free_irq(irq, NULL);
-}
-
-static int fw_load;
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-
-/*
- *     Install a Maui card. Needs mpu401 loaded already.
- */
-
-static int __init init_maui(void)
-{
-       printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-
-       if (cfg.io_base == -1 || cfg.irq == -1) {
-               printk(KERN_INFO "maui: irq and io must be set.\n");
-               return -EINVAL;
-       }
-
-       if (maui_os == NULL) {
-               fw_load = 1;
-               maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
-       }
-       if (probe_maui(&cfg) == 0)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit cleanup_maui(void)
-{
-       if (fw_load && maui_os)
-               vfree(maui_os);
-       unload_maui(&cfg);
-}
-
-module_init(init_maui);
-module_exit(cleanup_maui);
-
-#ifndef MODULE
-static int __init setup_maui(char *str)
-{
-        /* io, irq */
-       int ints[3];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io = ints[1];
-       irq = ints[2];
-
-       return 1;
-}
-
-__setup("maui=", setup_maui);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/midi_syms.c b/sound/oss/midi_syms.c
deleted file mode 100644 (file)
index 5b146dd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Exported symbols for midi driver.
- */
-
-#include <linux/module.h>
-
-char midi_syms_symbol;
-
-#include "sound_config.h"
-#define _MIDI_SYNTH_C_
-#include "midi_synth.h"
-
-EXPORT_SYMBOL(do_midi_msg);
-EXPORT_SYMBOL(midi_synth_open);
-EXPORT_SYMBOL(midi_synth_close);
-EXPORT_SYMBOL(midi_synth_ioctl);
-EXPORT_SYMBOL(midi_synth_kill_note);
-EXPORT_SYMBOL(midi_synth_start_note);
-EXPORT_SYMBOL(midi_synth_set_instr);
-EXPORT_SYMBOL(midi_synth_reset);
-EXPORT_SYMBOL(midi_synth_hw_control);
-EXPORT_SYMBOL(midi_synth_aftertouch);
-EXPORT_SYMBOL(midi_synth_controller);
-EXPORT_SYMBOL(midi_synth_panning);
-EXPORT_SYMBOL(midi_synth_setup_voice);
-EXPORT_SYMBOL(midi_synth_send_sysex);
-EXPORT_SYMBOL(midi_synth_bender);
-EXPORT_SYMBOL(midi_synth_load_patch);
-EXPORT_SYMBOL(MIDIbuf_avail);
index 972edc62afd10d53ff95bd896f8aace2b86d5183..9e450988ed36eb91e6b1b35783e06c14a8343f65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/midi_synth.c
+ * sound/oss/midi_synth.c
  *
  * High level midi sequencer manager for dumb MIDI interfaces.
  */
@@ -84,6 +84,7 @@ do_midi_msg(int synthno, unsigned char *msg, int mlen)
                  ;
          }
 }
+EXPORT_SYMBOL(do_midi_msg);
 
 static void
 midi_outc(int midi_dev, int data)
@@ -276,6 +277,7 @@ int midi_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
                return -EINVAL;
        }
 }
+EXPORT_SYMBOL(midi_synth_ioctl);
 
 int
 midi_synth_kill_note(int dev, int channel, int note, int velocity)
@@ -342,6 +344,7 @@ midi_synth_kill_note(int dev, int channel, int note, int velocity)
 
        return 0;
 }
+EXPORT_SYMBOL(midi_synth_kill_note);
 
 int
 midi_synth_set_instr(int dev, int channel, int instr_no)
@@ -364,6 +367,7 @@ midi_synth_set_instr(int dev, int channel, int instr_no)
 
        return 0;
 }
+EXPORT_SYMBOL(midi_synth_set_instr);
 
 int
 midi_synth_start_note(int dev, int channel, int note, int velocity)
@@ -405,6 +409,7 @@ midi_synth_start_note(int dev, int channel, int note, int velocity)
          }
        return 0;
 }
+EXPORT_SYMBOL(midi_synth_start_note);
 
 void
 midi_synth_reset(int dev)
@@ -412,6 +417,7 @@ midi_synth_reset(int dev)
 
        leave_sysex(dev);
 }
+EXPORT_SYMBOL(midi_synth_reset);
 
 int
 midi_synth_open(int dev, int mode)
@@ -444,6 +450,7 @@ midi_synth_open(int dev, int mode)
 
        return 1;
 }
+EXPORT_SYMBOL(midi_synth_open);
 
 void
 midi_synth_close(int dev)
@@ -459,11 +466,13 @@ midi_synth_close(int dev)
 
        midi_devs[orig_dev]->close(orig_dev);
 }
+EXPORT_SYMBOL(midi_synth_close);
 
 void
 midi_synth_hw_control(int dev, unsigned char *event)
 {
 }
+EXPORT_SYMBOL(midi_synth_hw_control);
 
 int
 midi_synth_load_patch(int dev, int format, const char __user *addr,
@@ -542,11 +551,13 @@ midi_synth_load_patch(int dev, int format, const char __user *addr,
                midi_outc(orig_dev, 0xf7);
        return 0;
 }
-  
+EXPORT_SYMBOL(midi_synth_load_patch);
+
 void midi_synth_panning(int dev, int channel, int pressure)
 {
 }
-  
+EXPORT_SYMBOL(midi_synth_panning);
+
 void midi_synth_aftertouch(int dev, int channel, int pressure)
 {
        int             orig_dev = synth_devs[dev]->midi_dev;
@@ -576,6 +587,7 @@ void midi_synth_aftertouch(int dev, int channel, int pressure)
 
        midi_outc(orig_dev, pressure);
 }
+EXPORT_SYMBOL(midi_synth_aftertouch);
 
 void
 midi_synth_controller(int dev, int channel, int ctrl_num, int value)
@@ -604,6 +616,7 @@ midi_synth_controller(int dev, int channel, int ctrl_num, int value)
        midi_outc(orig_dev, ctrl_num);
        midi_outc(orig_dev, value & 0x7f);
 }
+EXPORT_SYMBOL(midi_synth_controller);
 
 void
 midi_synth_bender(int dev, int channel, int value)
@@ -635,11 +648,13 @@ midi_synth_bender(int dev, int channel, int value)
        midi_outc(orig_dev, value & 0x7f);
        midi_outc(orig_dev, (value >> 7) & 0x7f);
 }
+EXPORT_SYMBOL(midi_synth_bender);
 
 void
 midi_synth_setup_voice(int dev, int voice, int channel)
 {
 }
+EXPORT_SYMBOL(midi_synth_setup_voice);
 
 int
 midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
@@ -695,3 +710,5 @@ midi_synth_send_sysex(int dev, unsigned char *bytes, int len)
 
        return 0;
 }
+EXPORT_SYMBOL(midi_synth_send_sysex);
+
index 6982556ded56fd352035cd772f53dff5959ce110..a40be0cf1d97f42bf6a180312afbc10b15c7a5bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/midibuf.c
+ * sound/oss/midibuf.c
  *
  * Device file manager for /dev/midi#
  */
@@ -414,18 +414,11 @@ unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
 }
 
 
-void MIDIbuf_init(void)
-{
-       /* drag in midi_syms.o */
-       {
-               extern char midi_syms_symbol;
-               midi_syms_symbol = 0;
-       }
-}
-
 int MIDIbuf_avail(int dev)
 {
        if (midi_in_buf[dev])
                return DATA_AVAIL (midi_in_buf[dev]);
        return 0;
 }
+EXPORT_SYMBOL(MIDIbuf_avail);
+
index 0aac54c68f01fa13c124ee5715c4f6f0b9b23124..162d07cc489f6fba5411c8ccb8b884868d0ef11c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/mpu401.c
+ * sound/oss/mpu401.c
  *
  * The low level driver for Roland MPU-401 compatible Midi cards.
  */
@@ -432,16 +432,7 @@ static void mpu401_input_loop(struct mpu_config *devc)
        devc->m_busy = 0;
 }
 
-int intchk_mpu401(void *dev_id)
-{
-       struct mpu_config *devc;
-       int dev = (int) dev_id;
-
-       devc = &dev_conf[dev];
-       return input_avail(devc);
-}
-
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        struct mpu_config *devc;
        int dev = (int) dev_id;
@@ -1761,8 +1752,6 @@ static int mpu_timer_init(int midi_dev)
 EXPORT_SYMBOL(probe_mpu401);
 EXPORT_SYMBOL(attach_mpu401);
 EXPORT_SYMBOL(unload_mpu401);
-EXPORT_SYMBOL(intchk_mpu401);
-EXPORT_SYMBOL(mpuintr);
 
 static struct address_info cfg;
 
index bdc5bde641e6b7fc56dfbb1b2e40df9bda0cf9bd..84c0e9522ef7e674cc75e86606e5585b3aae410c 100644 (file)
@@ -10,5 +10,3 @@ int probe_mpu401(struct address_info *hw_config, struct resource *ports);
 int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
 
-int intchk_mpu401(void *dev_id);
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
index a31734b7842fc9bff2cd0aab50292578c0966bed..4799bc77f987223308da7adc3aa22bae581122b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/opl3.c
+ * sound/oss/opl3.c
  *
  * A low level driver for Yamaha YM3812 and OPL-3 -chips
  *
diff --git a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c
deleted file mode 100644 (file)
index fe4907c..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * sound/opl3sa.c
- *
- * Low level driver for Yamaha YMF701B aka OPL3-SA chip
- * 
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- *     Alan Cox                Modularisation
- *     Christoph Hellwig       Adapted to module_init/module_exit
- *     Arnaldo C. de Melo      got rid of attach_uart401
- *
- * FIXME:
- *     Check for install of mpu etc is wrong, should check result of the mss stuff
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-
-#undef  SB_OK
-
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "mpu401.h"
-
-#ifdef SB_OK
-#include "sb.h"
-static int sb_initialized;
-#endif
-
-static DEFINE_SPINLOCK(lock);
-
-static unsigned char opl3sa_read(int addr)
-{
-       unsigned long flags;
-       unsigned char tmp;
-
-       spin_lock_irqsave(&lock,flags);
-       outb((0x1d), 0xf86);    /* password */
-       outb(((unsigned char) addr), 0xf86);    /* address */
-       tmp = inb(0xf87);       /* data */
-       spin_unlock_irqrestore(&lock,flags);
-
-       return tmp;
-}
-
-static void opl3sa_write(int addr, int data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&lock,flags);
-       outb((0x1d), 0xf86);    /* password */
-       outb(((unsigned char) addr), 0xf86);    /* address */
-       outb(((unsigned char) data), 0xf87);    /* data */
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init opl3sa_detect(void)
-{
-       int tmp;
-
-       if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04)
-       {
-               DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
-               /* return 0; */
-       }
-
-       /*
-        * Check that the password feature has any effect
-        */
-       
-       if (inb(0xf87) == tmp)
-       {
-               DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
-               return 0;
-       }
-       tmp = (opl3sa_read(0x04) & 0xe0) >> 5;
-
-       if (tmp != 0 && tmp != 1)
-       {
-               DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
-               return 0;
-       }
-       DDB(printk("OPL3-SA mode %x detected\n", tmp));
-
-       opl3sa_write(0x01, 0x00);       /* Disable MSS */
-       opl3sa_write(0x02, 0x00);       /* Disable SB */
-       opl3sa_write(0x03, 0x00);       /* Disable MPU */
-
-       return 1;
-}
-
-/*
- *    Probe and attach routines for the Windows Sound System mode of
- *     OPL3-SA
- */
-
-static int __init probe_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-       unsigned char tmp = 0x24;       /* WSS enable */
-
-       /*
-        * Check if the IO port returns valid signature. The original MS Sound
-        * system returns 0x04 while some cards (OPL3-SA for example)
-        * return 0x00.
-        */
-
-       if (!opl3sa_detect())
-       {
-               printk(KERN_ERR "OSS: OPL3-SA chip not found\n");
-               return 0;
-       }
-       
-       switch (hw_config->io_base)
-       {
-               case 0x530:
-                       tmp |= 0x00;
-                       break;
-               case 0xe80:
-                       tmp |= 0x08;
-                       break;
-               case 0xf40:
-                       tmp |= 0x10;
-                       break;
-               case 0x604:
-                       tmp |= 0x18;
-                       break;
-               default:
-                       printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
-                 return 0;
-       }
-
-       opl3sa_write(0x01, tmp);        /* WSS setup register */
-
-       return probe_ms_sound(hw_config, ports);
-}
-
-static void __init attach_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-       int nm = num_mixers;
-
-       /* FIXME */
-       attach_ms_sound(hw_config, ports, THIS_MODULE);
-       if (num_mixers > nm)    /* A mixer was installed */
-       {
-               AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
-               AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
-               AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-       }
-}
-
-
-static int __init probe_opl3sa_mpu(struct address_info *hw_config)
-{
-       unsigned char conf;
-       static signed char irq_bits[] = {
-               -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
-       };
-
-       if (hw_config->irq > 10)
-       {
-               printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-       if (irq_bits[hw_config->irq] == -1)
-       {
-               printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-       switch (hw_config->io_base)
-       {
-               case 0x330:
-                       conf = 0x00;
-                       break;
-               case 0x332:
-                       conf = 0x20;
-                       break;
-               case 0x334:
-                       conf = 0x40;
-                       break;
-               case 0x300:
-                       conf = 0x60;
-                       break;
-               default:
-                       return 0;       /* Invalid port */
-       }
-
-       conf |= 0x83;           /* MPU & OPL3 (synth) & game port enable */
-       conf |= irq_bits[hw_config->irq] << 2;
-
-       opl3sa_write(0x03, conf);
-
-       hw_config->name = "OPL3-SA (MPU401)";
-
-       return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_opl3sa_wss(struct address_info *hw_config)
-{
-       int dma2 = hw_config->dma2;
-
-       if (dma2 == -1)
-               dma2 = hw_config->dma;
-
-       release_region(0xf86, 2);
-       release_region(hw_config->io_base, 4);
-
-       ad1848_unload(hw_config->io_base + 4,
-                     hw_config->irq,
-                     hw_config->dma,
-                     dma2,
-                     0);
-       sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config)
-{
-       unload_uart401(hw_config);
-}
-
-#ifdef SB_OK
-static inline void __exit unload_opl3sa_sb(struct address_info *hw_config)
-{
-       sb_dsp_unload(hw_config);
-}
-#endif
-
-static int found_mpu;
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int __initdata io       = -1;
-static int __initdata irq      = -1;
-static int __initdata dma      = -1;
-static int __initdata dma2     = -1;
-static int __initdata mpu_io   = -1;
-static int __initdata mpu_irq  = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-
-static int __init init_opl3sa(void)
-{
-       struct resource *ports;
-       if (io == -1 || irq == -1 || dma == -1) {
-               printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
-               return -EINVAL;
-       }
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma2;
-       
-       cfg_mpu.io_base = mpu_io;
-       cfg_mpu.irq = mpu_irq;
-
-       ports = request_region(io + 4, 4, "ad1848");
-       if (!ports)
-               return -EBUSY;
-
-       if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ {
-               release_region(io + 4, 4);
-               return 0;
-       }
-
-       if (!request_region(io, 4, "WSS config")) {
-               release_region(0x86, 2);
-               release_region(io + 4, 4);
-               return 0;
-       }
-
-       if (probe_opl3sa_wss(&cfg, ports) == 0) {
-               release_region(0xf86, 2);
-               release_region(io, 4);
-               release_region(io + 4, 4);
-               return -ENODEV;
-       }
-
-       found_mpu=probe_opl3sa_mpu(&cfg_mpu);
-
-       attach_opl3sa_wss(&cfg, ports);
-       return 0;
-}
-
-static void __exit cleanup_opl3sa(void)
-{
-       if(found_mpu)
-               unload_opl3sa_mpu(&cfg_mpu);
-       unload_opl3sa_wss(&cfg);
-}
-
-module_init(init_opl3sa);
-module_exit(cleanup_opl3sa);
-
-#ifndef MODULE
-static int __init setup_opl3sa(char *str)
-{
-       /* io, irq, dma, dma2, mpu_io, mpu_irq */
-       int ints[7];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma2    = ints[4];
-       mpu_io  = ints[5];
-       mpu_irq = ints[6];
-
-       return 1;
-}
-
-__setup("opl3sa=", setup_opl3sa);
-#endif
-MODULE_LICENSE("GPL");
index aec05a2bfc8717ddb2f4999e1dd638a509fd4471..e20051f1be4d7b0efcdc3a88eeb004ae7a963dfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/opl3sa2.c
+ * sound/oss/opl3sa2.c
  *
  * A low level driver for Yamaha OPL3-SA2 and SA3 cards.
  * NOTE: All traces of the name OPL3-SAx have now (December 2000) been
index 97666007b274f4961625dcd836413609b52f8824..4ebb9638746ecbb97dc58fe98489c1425ce2a0c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/pas2_card.c
+ * sound/oss/pas2_card.c
  *
  * Detection routine for the Pro Audio Spectrum cards.
  */
index 79d6a5827b6d79bdbb72000d99e26704aa945877..1122d10a20c3a3737fb51f5489b1b09bdc1bbf94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/pas2_midi.c
+ * sound/oss/pas2_midi.c
  *
  * The low level driver for the PAS Midi Interface.
  */
index 4aade530458743fb3b51c05a37289571ca1438c8..a0bcb85c39046a8c4878b6367e6bd2cc938e2140 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * sound/pas2_mixer.c
+ * sound/oss/pas2_mixer.c
  *
  * Mixer routines for the Pro Audio Spectrum cards.
  */
index 37ee234b587c86744918e49d49bc8fd34e1f6eb2..ece428b2ba9fef34319670b25039bf5783c5bfe6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/pss.c
+ * sound/oss/pss.c
  *
  * The low level driver for the Personal Sound System (ECHO ESC614).
  *
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
deleted file mode 100644 (file)
index f17d25b..0000000
+++ /dev/null
@@ -1,1857 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-   based on es1370.c
-
-
-
-   *  10 Jan 2001: 0.1 initial version
-   *  19 Jan 2001: 0.2 fixed bug in select()
-   *  27 Apr 2001: 0.3 more than one card usable
-   *  11 May 2001: 0.4 fixed for SMP, included into kernel source tree
-   *  17 May 2001: 0.5 draining code didn't work on new cards
-   *  18 May 2001: 0.6 remove synchronize_irq() call 
-   *  17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards
-   *   2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!)
-                       Marcus Meissner <Marcus.Meissner@caldera.de>
-
-                      Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-                      HP20020108 fixed handling of "large" read()
-                      HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-                      HP20020118 made mixer ioctl and handling of devices>1 more safe
-                      HP20020201 fixed handling of "large" read() properly
-                      added REV 1.5 S/P-DIF receiver support
-                      SNDCTL_DSP_SPEED now returns the actual speed
-   *  10 Aug 2002: added synchronize_irq() again
-
-TODO:
-   - test more than one card --- done
-   - check for pci IOREGION (see es1370) in rme96xx_probe ??
-   - error detection
-   - mmap interface
-   - mixer mmap interface
-   - mixer ioctl
-   - get rid of noise upon first open (why ??)
-   - allow multiple open (at least for read)
-   - allow multiple open for non overlapping regions
-   - recheck the multiple devices part (offsets of different devices, etc)
-   - do decent draining in _release --- done
-   - SMP support
-   - what about using fragstotal>2 for small fragsize? (HP20020118)
-   - add support for AFMT_S32_LE
-*/
-
-#ifndef RMEVERSION
-#define RMEVERSION "0.8"
-#endif
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-#include <asm/dma.h>
-#include <asm/page.h>
-
-#include "rme96xx.h"
-
-#define NR_DEVICE 2
-
-static int devices = 1;
-module_param(devices, int, 0);
-MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver");
-
-
-MODULE_AUTHOR("Guenter Geiger, geiger@debian.org");
-MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver");
-MODULE_LICENSE("GPL");
-
-
-#ifdef DEBUG
-#define DBG(x) printk("RME_DEBUG:");x
-#define COMM(x) printk("RME_COMM: " x "\n");
-#else
-#define DBG(x) while (0) {}
-#define COMM(x)
-#endif
-
-/*-------------------------------------------------------------------------- 
-                        Preporcessor Macros and Definitions
- --------------------------------------------------------------------------*/
-
-#define RME96xx_MAGIC 0x6473
-
-/* Registers-Space in offsets from base address with 16MByte size */
-
-#define RME96xx_IO_EXTENT     16l*1024l*1024l
-#define RME96xx_CHANNELS_PER_CARD 26
-
-/*                  Write - Register */
-
-/* 0,4,8,12,16,20,24,28 ... hardware init (erasing fifo-pointer intern) */
-#define RME96xx_num_of_init_regs   8
-
-#define RME96xx_init_buffer       (0/4)
-#define RME96xx_play_buffer       (32/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_rec_buffer        (36/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_control_register  (64/4)  /* exact meaning see below */
-#define RME96xx_irq_clear         (96/4)  /* irq acknowledge */
-#define RME96xx_time_code         (100/4) /* if used with alesis adat */
-#define RME96xx_thru_base         (128/4) /* 132...228 Thru for 26 channels */
-#define RME96xx_thru_channels     RME96xx_CHANNELS_PER_CARD
-
-/*                     Read Register */
-
-#define RME96xx_status_register    0     /* meaning see below */
-
-
-
-/* Status Register: */
-/* ------------------------------------------------------------------------ */
-#define RME96xx_IRQ          0x0000001 /* IRQ is High if not reset by RMExx_irq_clear */
-#define RME96xx_lock_2       0x0000002 /* ADAT 3-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_1       0x0000004 /* ADAT 2-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_0       0x0000008 /* ADAT 1-PLL: 1=locked, 0=unlocked */
-
-#define RME96xx_fs48         0x0000010 /* sample rate 0 ...44.1/88.2,  1 ... 48/96 Khz */
-#define RME96xx_wsel_rd      0x0000020 /* if Word-Clock is used and valid then 1 */
-#define RME96xx_buf_pos1     0x0000040 /* Bit 6..15 : Position of buffer-pointer in 64Bytes-blocks */
-#define RME96xx_buf_pos2     0x0000080 /* resolution +/- 1 64Byte/block (since 64Bytes bursts) */
-#define RME96xx_buf_pos3     0x0000100 /* 10 bits = 1024 values */
-#define RME96xx_buf_pos4     0x0000200 /* if we mask off the first 6 bits, we can take the status */
-#define RME96xx_buf_pos5     0x0000400 /* register as sample counter in the hardware buffer */
-#define RME96xx_buf_pos6     0x0000800 
-
-#define RME96xx_buf_pos7     0x0001000 
-#define RME96xx_buf_pos8     0x0002000 
-#define RME96xx_buf_pos9     0x0004000
-#define RME96xx_buf_pos10    0x0008000 
-
-#define RME96xx_sync_2       0x0010000 /* if ADAT-IN3 synced to system clock */
-#define RME96xx_sync_1       0x0020000 /* if ADAT-IN2 synced to system clock */
-#define RME96xx_sync_0       0x0040000 /* if ADAT-IN1 synced to system clock */
-#define RME96xx_DS_rd        0x0080000 /* 1=Double Speed, 0=Normal Speed */
-
-#define RME96xx_tc_busy      0x0100000 /* 1=time-code copy in progress (960ms) */
-#define RME96xx_tc_out       0x0200000 /* time-code out bit */
-#define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz  */
-#define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz, */
-
-#define RME96xx_F_2          0x1000000 /*  001=Rev 1.5+ external Crystal Chip */
-#define RME96xx_ERF          0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/
-#define RME96xx_buffer_id    0x4000000 /* toggles by each interrupt on rec/play */
-#define RME96xx_tc_valid     0x8000000 /* 1 = a signal is detected on time-code input */
-#define RME96xx_SPDIF_READ  0x10000000 /* byte available from Rev 1.5+ SPDIF interface */
-
-/* Status Register Fields */
-
-#define RME96xx_lock            (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2)
-#define RME96xx_sync            (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2)
-#define RME96xx_F               (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2)
-#define rme96xx_decode_spdif_rate(x) ((x)>>22)
-
-/* Bit 6..15 : h/w buffer pointer */
-#define RME96xx_buf_pos          0x000FFC0 
-/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
-   Rev G EEPROMS and Rev 1.5 cards or later.
-*/ 
-#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos))
-
-
-/* Control-Register: */                            
-/*--------------------------------------------------------------------------------*/
-
-#define RME96xx_start_bit      0x0001 /* start record/play */
-#define RME96xx_latency0       0x0002 /* Buffer size / latency */
-#define RME96xx_latency1       0x0004 /*   buffersize = 512Bytes * 2^n */
-#define RME96xx_latency2       0x0008 /*   0=64samples ... 7=8192samples */
-
-#define RME96xx_Master         0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */
-#define RME96xx_IE             0x0020 /* Interupt Enable */
-#define RME96xx_freq           0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
-#define RME96xx_freq1          0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */
-#define RME96xx_DS              0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME96xx_PRO            0x0200 /* SPDIF-OUT 0=consumer, 1=professional */
-#define RME96xx_EMP            0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */
-#define RME96xx_Dolby          0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */
-
-#define RME96xx_opt_out                0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */
-#define RME96xx_wsel            0x2000 /* use Wordclock as sync (overwrites master) */
-#define RME96xx_inp_0           0x4000 /* SPDIF-IN 00=optical (ADAT1), */
-#define RME96xx_inp_1           0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */
-
-#define RME96xx_SyncRef0       0x10000 /* preferred sync-source in autosync */
-#define RME96xx_SyncRef1       0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-
-#define RME96xx_SPDIF_RESET    (1<<18) /* Rev 1.5+: h/w SPDIF receiver */
-#define RME96xx_SPDIF_SELECT   (1<<19)
-#define RME96xx_SPDIF_CLOCK    (1<<20)
-#define RME96xx_SPDIF_WRITE    (1<<21)
-#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
-
-
-#define RME96xx_ctrl_init            (RME96xx_latency0 |\
-                                     RME96xx_Master |\
-                                     RME96xx_inp_1)
-                              
-
-
-/* Control register fields and shortcuts */
-
-#define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2)
-#define RME96xx_inp         (RME96xx_inp_0|RME96xx_inp_1)
-#define RME96xx_SyncRef    (RME96xx_SyncRef0|RME96xx_SyncRef1)
-#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL)
-
-/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1  (??? HP20020201) */
-
-#define RME96xx_SET_LATENCY(x)   (((x)&0x7)<<1)
-#define RME96xx_GET_LATENCY(x)   (((x)>>1)&0x7)
-#define RME96xx_SET_inp(x) (((x)&0x3)<<14)
-#define RME96xx_GET_inp(x)   (((x)>>14)&0x3)
-#define RME96xx_SET_SyncRef(x) (((x)&0x3)<<17)
-#define RME96xx_GET_SyncRef(x)   (((x)>>17)&0x3)
-
-
-/* buffer sizes */
-#define RME96xx_BYTES_PER_SAMPLE  4 /* sizeof(u32) */
-#define RME_16K 16*1024
-
-#define RME96xx_DMA_MAX_SAMPLES  (RME_16K)
-#define RME96xx_DMA_MAX_SIZE     (RME_16K * RME96xx_BYTES_PER_SAMPLE)
-#define RME96xx_DMA_MAX_SIZE_ALL (RME96xx_DMA_MAX_SIZE * RME96xx_CHANNELS_PER_CARD)
-
-#define RME96xx_NUM_OF_FRAGMENTS     2
-#define RME96xx_FRAGMENT_MAX_SIZE    (RME96xx_DMA_MAX_SIZE/2)
-#define RME96xx_FRAGMENT_MAX_SAMPLES (RME96xx_DMA_MAX_SAMPLES/2)
-#define RME96xx_MAX_LATENCY       7   /* 16k samples */
-
-
-#define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */
-#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */
-
-#define RME_MESS "rme96xx:"
-/*------------------------------------------------------------------------ 
-                  Types, struct and function declarations 
- ------------------------------------------------------------------------*/
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT RME_MESS" invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != RME96xx_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-
-static struct file_operations rme96xx_audio_fops;
-static struct file_operations rme96xx_mixer_fops;
-static int numcards;
-
-typedef int32_t raw_sample_t;
-
-typedef struct _rme96xx_info {
-
-       /* hardware settings */
-       int magic;
-       struct pci_dev * pcidev; /* pci_dev structure */
-       unsigned long __iomem *iobase;  
-       unsigned int irq;
-
-       /* list of rme96xx devices */
-       struct list_head devs;
-
-       spinlock_t lock;
-
-       u32 *recbuf;             /* memory for rec buffer */
-       u32 *playbuf;            /* memory for play buffer */
-
-       u32 control_register;
-
-       u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
-
-       int hw_rev;             /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
-       char *card_name;        /* hammerfall or hammerfall light names */
-
-       int open_count;         /* unused ???   HP20020201 */
-
-       int rate;
-       int latency;
-       unsigned int fragsize;
-       int started;
-
-       int hwptr; /* can be negativ because of pci burst offset  */
-       unsigned int hwbufid;  /* set by interrupt, buffer which is written/read now */
-       
-       struct dmabuf {
-
-               unsigned int format;
-               int formatshift;
-               int inchannels;       /* number of channels for device */
-               int outchannels;       /* number of channels for device */
-               int mono; /* if true, we play mono on 2 channels */
-               int inoffset; /* which channel is considered the first one */
-               int outoffset;
-               
-               /* state */
-               int opened;               /* open() made */
-               int started;              /* first write/read */
-               int mmapped;              /* mmap */
-               int open_mode;
-
-               struct _rme96xx_info *s;  
-
-               /* pointer to read/write position in buffer */
-               unsigned readptr;          
-               unsigned writeptr;          
-
-               unsigned error; /* over/underruns cleared on sync again */
-
-               /* waiting and locking */
-               wait_queue_head_t wait;
-               struct mutex  open_mutex;
-               wait_queue_head_t open_wait;
-
-       } dma[RME96xx_MAX_DEVS]; 
-
-       int dspnum[RME96xx_MAX_DEVS];  /* register with sound subsystem */ 
-       int mixer;  /* register with sound subsystem */ 
-} rme96xx_info;
-
-
-/* fiddling with the card (first level hardware control) */
-
-static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask)
-{
-
-       s->control_register|=mask;
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask)
-{
-
-       s->control_register&=(~mask);
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
-{
-       int val;
-       u32 status;
-       status = readl(s->iobase + RME96xx_status_register);
-       val = (status & RME96xx_fs48) ? 48000 : 44100;
-       if (status & RME96xx_DS_rd)
-               val *= 2;
-       return val;
-}
-
-static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
-{
-       int val;
-       val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
-       if (s->control_register & RME96xx_DS)
-               val *= 2;
-       return val;
-}
-
-
-/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver   HP 20020201 */
-
-static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff)
-{
-       if (onoff) 
-               s->control_register |= mask;
-       else 
-               s->control_register &= ~mask;
-               
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-}
-
-static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val)
-{
-       long mask;
-       long i;
-
-       for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
-               if (val & mask)
-                       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1);
-               else 
-                       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0);
-
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-       }
-}
-
-static int rme96xx_spdif_read_byte (rme96xx_info* s)
-{
-       long mask;
-       long val;
-       long i;
-
-       val = 0;
-
-       for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-               if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ)
-                       val |= mask;
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-       }
-
-       return val;
-}
-
-static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data)
-{
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-       rme96xx_spdif_write_byte (s, 0x20);
-       rme96xx_spdif_write_byte (s, address);
-       rme96xx_spdif_write_byte (s, data);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-}
-
-
-static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address)
-{
-       int ret;
-
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-       rme96xx_spdif_write_byte (s, 0x20);
-       rme96xx_spdif_write_byte (s, address);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-
-       rme96xx_spdif_write_byte (s, 0x21);
-       ret = rme96xx_spdif_read_byte (s);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-
-       return ret;
-}
-
-static void rme96xx_initialize_spdif_receiver (rme96xx_info* s)
-{
-       /* XXX what unsets this ? */
-       /* no idea ???   HP 20020201 */
-
-       s->control_register |= RME96xx_SPDIF_RESET;
-
-       rme96xx_write_spdif_codec (s, 4, 0x40);
-       rme96xx_write_spdif_codec (s, 17, 0x13);
-       rme96xx_write_spdif_codec (s, 6, 0x02);
-}
-
-static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate)
-{
-       unsigned int rate_bits;
-
-       *spdifrate = 0x1;
-       if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) {
-               return -1;      /* error condition */
-       }
-       
-       if (s->hw_rev == 15) {
-
-               int x, y, ret;
-               
-               x = rme96xx_spdif_read_codec (s, 30);
-
-               if (x != 0) 
-                       y = 48000 * 64 / x;
-               else
-                       y = 0;
-
-               if      (y > 30400 && y < 33600)  {ret = 32000; *spdifrate = 0x7;}
-               else if (y > 41900 && y < 46000)  {ret = 44100; *spdifrate = 0x6;}
-               else if (y > 46000 && y < 50400)  {ret = 48000; *spdifrate = 0x5;}
-               else if (y > 60800 && y < 67200)  {ret = 64000; *spdifrate = 0x0;}
-               else if (y > 83700 && y < 92000)  {ret = 88200; *spdifrate = 0x4;}
-               else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;}
-               else                              {ret = 0; *spdifrate = 0x1;}
-               return ret;
-       }
-
-       rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F;
-
-       switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) {
-       case 0x7:
-               return 32000;
-               break;
-
-       case 0x6:
-               return 44100;
-               break;
-
-       case 0x5:
-               return 48000;
-               break;
-
-       case 0x4:
-               return 88200;
-               break;
-
-       case 0x3:
-               return 96000;
-               break;
-
-       case 0x0:
-               return 64000;
-               break;
-
-       default:
-               /* was an ALSA warning ...
-                 snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
-                 s->card_name, rate_bits);
-               */
-               return 0;
-               break;
-       }
-}
-
-/* end of code from ALSA card-rme9652.c */
-
-
-
-/* the hwbuf in the status register seems to have some jitter, to get rid of
-   it, we first only let the numbers grow, to be on the secure side we 
-   subtract a certain amount RME96xx_BURSTBYTES from the resulting number */
-
-/* the function returns the hardware pointer in bytes */
-#define RME96xx_BURSTBYTES -64  /* bytes by which hwptr could be off */
-
-static inline int rme96xx_gethwptr(rme96xx_info* s,int exact)
-{
-       unsigned long flags;
-       if (exact) {
-               unsigned int hwp;
-/* the hwptr seems to be rather unreliable :(, so we don't use it */
-               spin_lock_irqsave(&s->lock,flags);
-               
-               hwp  = readl(s->iobase + RME96xx_status_register) & 0xffc0;
-               s->hwptr = (hwp < s->hwptr) ? s->hwptr : hwp;
-//             s->hwptr = hwp;
-
-               spin_unlock_irqrestore(&s->lock,flags);
-               return (s->hwptr+RME96xx_BURSTBYTES) & ((s->fragsize<<1)-1);
-       }
-       return (s->hwbufid ? s->fragsize : 0);
-}
-
-static inline void rme96xx_setlatency(rme96xx_info* s,int l)
-{
-       s->latency = l;
-       s->fragsize = 1<<(8+l);
-       rme96xx_unset_ctrl(s,RME96xx_latency);
-       rme96xx_set_ctrl(s,RME96xx_SET_LATENCY(l));     
-}
-
-
-static void rme96xx_clearbufs(struct dmabuf* dma)
-{
-       int i,j;
-       unsigned long flags;
-
-       /* clear dmabufs */
-       for(i=0;i<devices;i++) {
-               for (j=0;j<dma->outchannels + dma->mono;j++)
-                       memset(&dma->s->playbuf[(dma->outoffset + j)*RME96xx_DMA_MAX_SAMPLES], 
-                              0, RME96xx_DMA_MAX_SIZE);
-       }
-       spin_lock_irqsave(&dma->s->lock,flags);
-       dma->writeptr = 0;
-       dma->readptr = 0;
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-}
-
-static int rme96xx_startcard(rme96xx_info *s,int stop)
-{
-       int i;
-       unsigned long flags;
-
-       COMM       ("startcard");
-       if(s->control_register & RME96xx_IE){
-               /* disable interrupt first */
-               
-               rme96xx_unset_ctrl( s,RME96xx_start_bit );
-               udelay(10);
-               rme96xx_unset_ctrl( s,RME96xx_IE);
-               spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-               s->started = 0;
-               spin_unlock_irqrestore(&s->lock,flags);
-               if (stop) {
-                    COMM("Sound card stopped");
-                    return 1;
-               }
-       }
-       COMM       ("interrupt disabled");
-       /* first initialize all pointers on card */
-       for(i=0;i<RME96xx_num_of_init_regs;i++){
-               writel(0,s->iobase + i);
-               udelay(10); /* ?? */
-       }
-       COMM       ("regs cleaned");
-
-       spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-       udelay(10);
-       s->started = 1;
-       s->hwptr = 0;
-       spin_unlock_irqrestore(&s->lock,flags);
-
-       rme96xx_set_ctrl( s, RME96xx_IE | RME96xx_start_bit);
-
-
-       COMM("Sound card started");
-  
-       return 1;
-}
-
-
-static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp)
-{
-       int cnt;
-       int  swptr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dma->s->lock,flags); 
-       swptr = dma->writeptr;
-       cnt = (hwp - swptr);
-       
-       if (cnt < 0) {
-            cnt = ((dma->s->fragsize<<1) - swptr);
-       }
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-       return cnt;
-}
-
-static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
-{
-       int cnt;
-       int  swptr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dma->s->lock,flags); 
-       swptr = dma->readptr;
-       cnt = (hwp - swptr);
-        
-       if (cnt < 0) {
-               cnt = ((dma->s->fragsize<<1) - swptr);
-       }
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-       return cnt;
-}
-
-
-static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
-{
-       int swptr = dma->writeptr;
-       switch (dma->format) {
-       case AFMT_S32_BLOCKED:
-       {
-            char __user * buf = (char __user *)buffer;
-            int cnt = count/dma->outchannels;
-            int i;
-            for (i=0;i < dma->outchannels;i++) {
-                 char* hwbuf =(char*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-                 hwbuf+=swptr;
-
-                 if (copy_from_user(hwbuf,buf, cnt))
-                      return -1;
-                 buf+=hop;
-            }
-            swptr+=cnt;
-            break;
-       }
-       case AFMT_S16_LE:
-       {
-            int i,j;
-            int cnt = count/dma->outchannels;
-            for (i=0;i < dma->outchannels + dma->mono;i++) {
-                    short __user * sbuf = (short __user *)buffer + i*(!dma->mono);
-                    short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];          
-                    hwbuf+=(swptr>>1);
-                    for (j=0;j<(cnt>>1);j++) {
-                            hwbuf++; /* skip the low 16 bits */
-                            __get_user(*hwbuf++,sbuf++);
-                            sbuf+=(dma->outchannels-1);
-                    }
-            }
-            swptr += (cnt<<1);
-            break;
-       }
-       default:
-            printk(RME_MESS" unsupported format\n");
-            return -1;
-       } /* switch */
-
-       swptr&=((dma->s->fragsize<<1) -1);
-       dma->writeptr = swptr;
-
-       return 0;
-}
-
-/* The count argument is the number of bytes */
-static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
-{
-       int swptr = dma->readptr;
-       switch (dma->format) {
-       case AFMT_S32_BLOCKED:
-       {
-            char __user * buf = (char __user *)buffer;
-            int cnt = count/dma->inchannels;
-            int i;
-
-            for (i=0;i < dma->inchannels;i++) {
-                 char* hwbuf =(char*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-                 hwbuf+=swptr;
-
-                 if (copy_to_user(buf,hwbuf,cnt))
-                      return -1;
-                 buf+=hop;
-            }
-            swptr+=cnt;
-            break;
-       }
-       case AFMT_S16_LE:
-       {
-            int i,j;
-            int cnt = count/dma->inchannels;
-            for (i=0;i < dma->inchannels;i++) {
-                 short __user * sbuf = (short __user *)buffer + i;
-                 short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];       
-                 hwbuf+=(swptr>>1);
-                 for (j=0;j<(cnt>>1);j++) {
-                      hwbuf++;
-                      __put_user(*hwbuf++,sbuf++);
-                      sbuf+=(dma->inchannels-1);
-                 }
-            }
-            swptr += (cnt<<1);
-            break;
-       }
-       default:
-            printk(RME_MESS" unsupported format\n");
-            return -1;
-       } /* switch */
-       
-       swptr&=((dma->s->fragsize<<1) -1);      
-       dma->readptr = swptr;
-       return 0;
-}
-
-
-static irqreturn_t rme96xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       int i;
-       rme96xx_info *s = (rme96xx_info *)dev_id;
-       struct dmabuf *db;
-       u32 status;
-       unsigned long flags;
-
-       status = readl(s->iobase + RME96xx_status_register);
-       if (!(status & RME96xx_IRQ)) {
-               return IRQ_NONE;
-       }
-
-       spin_lock_irqsave(&s->lock,flags);
-       writel(0,s->iobase + RME96xx_irq_clear);
-
-       s->hwbufid = (status & RME96xx_buffer_id)>>26;  
-       if ((status & 0xffc0) <= 256) s->hwptr = 0; 
-       for(i=0;i<devices;i++)
-       {
-               db = &(s->dma[i]);
-               if(db->started > 0)
-                       wake_up(&(db->wait));           
-       }  
-       spin_unlock_irqrestore(&s->lock,flags);
-       return IRQ_HANDLED;
-}
-
-
-
-/*---------------------------------------------------------------------------- 
- PCI detection and module initialization stuff 
- ----------------------------------------------------------------------------*/
-
-static void* busmaster_malloc(int size) {
-     int pg; /* 2 s exponent of memory size */
-        char *buf;
-
-        DBG(printk("kernel malloc pages ..\n"));
-        
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        buf = (char *) __get_free_pages(GFP_KERNEL | GFP_DMA, pg);
-
-        if (buf) {
-                struct page* page, *last_page;
-
-                page = virt_to_page(buf);
-                last_page = page + (1 << pg);
-                DBG(printk("setting reserved bit\n"));
-                while (page < last_page) {
-                       SetPageReserved(page);
-                        page++;
-                }
-               return buf;
-        }
-       DBG(printk("allocated %ld",(long)buf));
-       return NULL;
-}
-
-static void busmaster_free(void* ptr,int size) {
-        int pg;
-       struct page* page, *last_page;
-
-        if (ptr == NULL)
-                return;
-
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        page = virt_to_page(ptr);
-        last_page = page + (1 << pg);
-        while (page < last_page) {
-               ClearPageReserved(page);
-               page++;
-       }
-       DBG(printk("freeing pages\n"));
-        free_pages((unsigned long) ptr, pg);
-       DBG(printk("done\n"));
-}
-
-/* initialize those parts of the info structure which are not pci detectable resources */
-
-static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) {
-
-       mutex_init(&dma->open_mutex);
-       init_waitqueue_head(&dma->open_wait);
-       init_waitqueue_head(&dma->wait);
-       dma->s = s; 
-       dma->error = 0;
-
-       dma->format = AFMT_S32_BLOCKED;
-       dma->formatshift = 0;
-       dma->inchannels = dma->outchannels = 1;
-       dma->inoffset = ioffset;
-       dma->outoffset = ooffset;
-
-       dma->opened=0;
-       dma->started=0;
-       dma->mmapped=0;
-       dma->open_mode=0;
-       dma->mono=0;
-
-       rme96xx_clearbufs(dma);
-       return 0;
-}
-
-
-static int rme96xx_init(rme96xx_info* s)
-{
-       int i;
-       int status;
-       unsigned short rev;
-
-       DBG(printk("%s\n", __FUNCTION__));
-       numcards++;
-
-       s->magic = RME96xx_MAGIC; 
-
-       spin_lock_init(&s->lock);
-
-       COMM            ("setup busmaster memory")
-       s->recbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-       s->playbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-
-       if (!s->recbuf || !s->playbuf) {
-               printk(KERN_ERR RME_MESS" Unable to allocate busmaster memory\n");
-               return -ENODEV;
-       }
-
-       COMM            ("setting rec and playbuffers")
-
-       writel((u32) virt_to_bus(s->recbuf),s->iobase + RME96xx_rec_buffer);
-       writel((u32) virt_to_bus(s->playbuf),s->iobase + RME96xx_play_buffer);
-
-       COMM             ("initializing control register")
-       rme96xx_unset_ctrl(s,0xffffffff);
-       rme96xx_set_ctrl(s,RME96xx_ctrl_init);
-
-
-       COMM              ("setup devices")     
-       for (i=0;i < devices;i++) {
-               struct dmabuf * dma = &s->dma[i];
-               rme96xx_dmabuf_init(s,dma,2*i,2*i);
-       }
-
-       /* code from ALSA card-rme9652.c   HP 20020201 */
-        /* Determine the h/w rev level of the card. This seems like
-          a particularly kludgy way to encode it, but its what RME
-          chose to do, so we follow them ...
-       */
-
-       status = readl(s->iobase + RME96xx_status_register);
-       if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) {
-               s->hw_rev = 15;
-       } else {
-               s->hw_rev = 11;
-       }
-
-       /* Differentiate between the standard Hammerfall, and the
-          "Light", which does not have the expansion board. This
-          method comes from information received from Mathhias
-          Clausen at RME. Display the EEPROM and h/w revID where
-          relevant.  
-       */
-
-       pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev);
-       switch (rev & 0xff) {
-       case 8: /* original eprom */
-               if (s->hw_rev == 15) {
-                       s->card_name = "RME Digi9636 (Rev 1.5)";
-               } else {
-                       s->card_name = "RME Digi9636";
-               }
-               break;
-       case 9: /* W36_G EPROM */
-               s->card_name = "RME Digi9636 (Rev G)";
-               break;
-       case 4: /* W52_G EPROM */
-               s->card_name = "RME Digi9652 (Rev G)";
-               break;
-       default:
-       case 3: /* original eprom */
-               if (s->hw_rev == 15) {
-                       s->card_name = "RME Digi9652 (Rev 1.5)";
-               } else {
-                       s->card_name = "RME Digi9652";
-               }
-               break;
-       }
-
-       printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); 
-
-       if (s->hw_rev == 15)
-               rme96xx_initialize_spdif_receiver (s);
-
-       s->started = 0;
-       rme96xx_setlatency(s,7);
-
-       printk(KERN_INFO RME_MESS" card %d initialized\n",numcards); 
-       return 0;
-}
-
-
-/* open uses this to figure out which device was opened .. this seems to be 
-   unnecessary complex */
-
-static LIST_HEAD(devs);
-
-static int __devinit rme96xx_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       int i;
-       rme96xx_info *s;
-
-       DBG(printk("%s\n", __FUNCTION__));
-       
-       if (pcidev->irq == 0) 
-               return -1;
-       if (!pci_dma_supported(pcidev, 0xffffffff)) {
-               printk(KERN_WARNING RME_MESS" architecture does not support 32bit PCI busmaster DMA\n");
-               return -1;
-       }
-       if (!(s = kmalloc(sizeof(rme96xx_info), GFP_KERNEL))) {
-               printk(KERN_WARNING RME_MESS" out of memory\n");
-               return -1;
-       }
-       memset(s, 0, sizeof(rme96xx_info));
-
-       s->pcidev = pcidev;
-       s->iobase = ioremap(pci_resource_start(pcidev, 0),RME96xx_IO_EXTENT);
-       s->irq = pcidev->irq;
-
-        DBG(printk("remapped iobase: %lx irq %d\n",(long)s->iobase,s->irq));
-
-       if (pci_enable_device(pcidev))
-               goto err_irq;
-       if (request_irq(s->irq, rme96xx_interrupt, IRQF_SHARED, "rme96xx", s)) {
-               printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       
-       /* initialize the card */
-
-       i = 0;
-       if (rme96xx_init(s) < 0) {
-               printk(KERN_ERR RME_MESS" initialization failed\n");
-               goto err_devices;
-       }
-       for (i=0;i<devices;i++) {
-               if ((s->dspnum[i] = register_sound_dsp(&rme96xx_audio_fops, -1)) < 0)
-                       goto err_devices;
-       }
-
-       if ((s->mixer = register_sound_mixer(&rme96xx_mixer_fops, -1)) < 0)
-               goto err_devices;
-
-       pci_set_drvdata(pcidev, s);
-       pcidev->dma_mask = 0xffffffff; /* ????? */
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-
-       DBG(printk("initialization successful\n"));
-       return 0;
-
-       /* error handler */
- err_devices:
-       while (i--) 
-               unregister_sound_dsp(s->dspnum[i]);
-       free_irq(s->irq,s);
- err_irq:
-       kfree(s);
-       return -1;
-}
-
-
-static void __devexit rme96xx_remove(struct pci_dev *dev)
-{
-       int i;
-       rme96xx_info *s = pci_get_drvdata(dev);
-
-       if (!s) {
-               printk(KERN_ERR"device structure not valid\n");
-               return ;
-       }
-
-       if (s->started) rme96xx_startcard(s,0);
-
-       i = devices;
-       while (i) {
-               i--;
-               unregister_sound_dsp(s->dspnum[i]);
-       }
-       
-       unregister_sound_mixer(s->mixer);
-       synchronize_irq(s->irq);
-       free_irq(s->irq,s);
-       busmaster_free(s->recbuf,RME96xx_DMA_MAX_SIZE_ALL);
-       busmaster_free(s->playbuf,RME96xx_DMA_MAX_SIZE_ALL);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-
-#ifndef PCI_VENDOR_ID_RME 
-#define PCI_VENDOR_ID_RME 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_RME9652
-#define PCI_DEVICE_ID_RME9652 0x3fc4
-#endif
-#ifndef PCI_ANY_ID
-#define PCI_ANY_ID 0
-#endif
-
-static struct pci_device_id id_table[] = {
-       {
-               .vendor    = PCI_VENDOR_ID_RME,
-               .device    = PCI_DEVICE_ID_RME9652,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver rme96xx_driver = {
-       .name     =  "rme96xx",
-       .id_table = id_table,
-       .probe    = rme96xx_probe,
-       .remove   = __devexit_p(rme96xx_remove),
-};
-
-static int __init init_rme96xx(void)
-{
-       printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
-       devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
-       printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
-        numcards = 0;
-       return pci_register_driver(&rme96xx_driver);
-}
-
-static void __exit cleanup_rme96xx(void)
-{
-       printk(KERN_INFO RME_MESS" unloading\n");
-       pci_unregister_driver(&rme96xx_driver);
-}
-
-module_init(init_rme96xx);
-module_exit(cleanup_rme96xx);
-
-
-
-
-
-/*-------------------------------------------------------------------------- 
-   Implementation of file operations 
----------------------------------------------------------------------------*/
-
-#define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED)
-/* AFTM_U8 is not (yet?) supported ...  HP20020201 */
-
-static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct dmabuf * dma = (struct dmabuf *)file->private_data; 
-       rme96xx_info *s = dma->s;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val = 0;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-
-       DBG(printk("ioctl %ud\n",cmd));
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-#if 0
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-#endif
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-//             rme96xx_clearbufs(dma);
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-/* generally it's not a problem if we change the speed 
-                       if (dma->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-                               return -EINVAL;
-*/
-                       spin_lock_irqsave(&s->lock, flags);
-
-                       switch (val) {
-                       case 44100:
-                       case 88200:
-                               rme96xx_unset_ctrl(s,RME96xx_freq);
-                               break;
-                       case 48000: 
-                       case 96000: 
-                               rme96xx_set_ctrl(s,RME96xx_freq);
-                               break;
-                       /* just report current rate as default
-                          e.g. use 0 to "select" current digital input rate
-                       default:
-                               rme96xx_unset_ctrl(s,RME96xx_freq);
-                               val = 44100;
-                       */
-                       }
-                       if (val > 50000)
-                               rme96xx_set_ctrl(s,RME96xx_DS);
-                       else
-                               rme96xx_unset_ctrl(s,RME96xx_DS);
-                       /* set val to actual value  HP 20020201 */
-                       /* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */
-                       if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel))
-                               val = rme96xx_get_sample_rate_ctrl(s);
-                       else
-                               val = rme96xx_get_sample_rate_status(s);
-                       s->rate = val;
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               DBG(printk("speed set to %d\n",val));
-               return put_user(val, p);
-               
-        case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */
-                if (get_user(val, p))
-                       return -EFAULT;
-               
-               if (!val) {
-                       DBG(printk("setting to mono\n")); 
-                       dma->mono=1; 
-                       dma->inchannels = 1;
-                       dma->outchannels = 1;
-               }
-               else {
-                       DBG(printk("setting to stereo\n")); 
-                       dma->mono = 0;
-                       dma->inchannels = 2;
-                       dma->outchannels = 2;
-               }
-               return 0;
-        case SNDCTL_DSP_CHANNELS:
-               /* remember to check for resonable offset/channel pairs here */
-                if (get_user(val, p))
-                       return -EFAULT;
-
-               if (file->f_mode & FMODE_WRITE) {                       
-                       if (val > 0 && (dma->outoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-                               dma->outchannels = val;
-                       else
-                               dma->outchannels = val = 2;
-                       DBG(printk("setting to outchannels %d\n",val)); 
-               }
-               if (file->f_mode & FMODE_READ) {
-                       if (val > 0 && (dma->inoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-                               dma->inchannels = val;
-                       else
-                               dma->inchannels = val = 2;
-                       DBG(printk("setting to inchannels %d\n",val)); 
-               }
-
-               dma->mono=0;
-
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(RME96xx_FMT, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               DBG(printk("setting to format %x\n",val)); 
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (val & RME96xx_FMT)
-                               dma->format = val;
-                       switch (dma->format) {
-                       case AFMT_S16_LE:
-                               dma->formatshift=1;
-                               break;
-                       case AFMT_S32_BLOCKED:
-                               dma->formatshift=0;
-                               break;
-                       }
-               }
-               return put_user(dma->format, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-#if 0
-               if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-                       val |= PCM_ENABLE_OUTPUT;
-#endif
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-#if 0
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-                                       return ret;
-                               start_dac2(s);
-                       } else
-                               stop_dac2(s);
-               }
-#endif
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-
-
-               count = rme96xx_getospace(dma,val);
-               if (!s->started) count = s->fragsize*2;
-               abinfo.fragsize =(s->fragsize*dma->outchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->outchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = (count > s->fragsize); 
-
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-
-               count = rme96xx_getispace(dma,val);
-
-               abinfo.fragsize = (s->fragsize*dma->inchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->inchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = count > s->fragsize; 
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY: /* What should this exactly do ? ,
-                                     ATM it is just abinfo.bytes */
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-               count = val - dma->readptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-               return put_user(count, p);
-
-
-/* check out how to use mmaped mode (can only be blocked !!!) */
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               val = rme96xx_gethwptr(dma->s,0);
-               spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-               count = val - dma->readptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-               if (dma->mmapped)
-                       dma->readptr &= s->fragsize<<1;
-               spin_unlock_irqrestore(&s->lock,flags);
-
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               val = rme96xx_gethwptr(dma->s,0);
-               spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-               count = val - dma->writeptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-               if (dma->mmapped)
-                       dma->writeptr &= s->fragsize<<1;
-               spin_unlock_irqrestore(&s->lock,flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-        case SNDCTL_DSP_GETBLKSIZE:
-            return put_user(s->fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               val&=0xffff;
-               val -= 7;
-               if (val < 0) val = 0;
-               if (val > 7) val = 7;
-               rme96xx_setlatency(s,val);
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-#if 0
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac2.subdivision = val;
-#endif         
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               /* HP20020201 */
-               s->rate = rme96xx_get_sample_rate_status(s);
-               return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user(dma->outchannels, p);
-
-        case SOUND_PCM_READ_BITS:
-               switch (dma->format) {
-                       case AFMT_S32_BLOCKED:
-                               val = 32;
-                               break;
-                       case AFMT_S16_LE:
-                               val = 16;
-                               break;
-               }
-               return put_user(val, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-
-
-       return -ENODEV;
-}
-
-
-
-static int rme96xx_open(struct inode *in, struct file *f)
-{
-       int minor = iminor(in);
-       struct list_head *list;
-       int devnum;
-       rme96xx_info *s;
-       struct dmabuf* dma;
-       DECLARE_WAITQUEUE(wait, current); 
-
-       DBG(printk("device num %d open\n",devnum));
-
-       nonseekable_open(in, f);
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, rme96xx_info, devs);
-               for (devnum=0; devnum<devices; devnum++)
-                       if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
-                               break;
-               if (devnum<devices)
-                       break;
-       }
-               VALIDATE_STATE(s);
-
-       dma = &s->dma[devnum];
-       f->private_data = dma;
-       /* wait for device to become free */
-       mutex_lock(&dma->open_mutex);
-       while (dma->open_mode & f->f_mode) {
-               if (f->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&dma->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&dma->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&dma->open_mutex);
-               schedule();
-               remove_wait_queue(&dma->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&dma->open_mutex);
-       }
-
-       COMM                ("hardware open")
-
-       if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
-
-       dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
-       dma->opened = 1;
-       mutex_unlock(&dma->open_mutex);
-
-       DBG(printk("device num %d open finished\n",devnum));
-       return 0;
-}
-
-static int rme96xx_release(struct inode *in, struct file *file)
-{
-       struct dmabuf * dma = (struct dmabuf*) file->private_data;
-       /* int hwp;  ... was unused   HP20020201 */
-       DBG(printk("%s\n", __FUNCTION__));
-
-       COMM          ("draining")
-       if (dma->open_mode & FMODE_WRITE) {
-#if 0 /* Why doesn't this work with some cards ?? */
-            hwp = rme96xx_gethwptr(dma->s,0);
-            while (rme96xx_getospace(dma,hwp)) {
-                 interruptible_sleep_on(&(dma->wait));
-                 hwp = rme96xx_gethwptr(dma->s,0);
-            }
-#endif
-            rme96xx_clearbufs(dma);
-       }
-
-       dma->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-       if (!(dma->open_mode & (FMODE_READ|FMODE_WRITE))) {
-            dma->opened = 0;
-            if (dma->s->started) rme96xx_startcard(dma->s,1);
-       }
-
-       wake_up(&dma->open_wait);
-       mutex_unlock(&dma->open_mutex);
-
-       return 0;
-}
-
-
-static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       ssize_t ret = 0;
-       int cnt; /* number of bytes from "buffer" that will/can be used */
-       int hop = count/dma->outchannels;
-       int hwp;
-       int exact = (file->f_flags & O_NONBLOCK); 
-
-
-       if(dma == NULL || (dma->s) == NULL) 
-               return -ENXIO;
-
-       if (dma->mmapped || !dma->opened)
-               return -ENXIO;
-
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-
-       if (! (dma->open_mode  & FMODE_WRITE))
-                return -ENXIO;
-
-       if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-       if(!(dma->started)){             
-               COMM          ("first write")
-                       
-               dma->readptr = hwp;
-               dma->writeptr = hwp;
-               dma->started = 1;
-       }
-
-       while (count > 0) {
-               cnt = rme96xx_getospace(dma,hwp);               
-               cnt>>=dma->formatshift;
-               cnt*=dma->outchannels;
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt != 0) {
-                       if (rme96xx_copyfromuser(dma,buffer,cnt,hop))
-                               return ret ? ret : -EFAULT;
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-                       if (count == 0) return ret;
-               }
-               if (file->f_flags & O_NONBLOCK)
-                       return ret ? ret : -EAGAIN;
-               
-               if ((hwp - dma->writeptr) <= 0) {
-                       interruptible_sleep_on(&(dma->wait));
-                       
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-               }                       
-
-               hwp = rme96xx_gethwptr(dma->s,exact);
-
-       }; /* count > 0 */
-
-       return ret;
-}
-
-static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{ 
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       ssize_t ret = 0;
-       int cnt; /* number of bytes from "buffer" that will/can be used */
-       int hop = count/dma->inchannels;
-       int hwp;
-       int exact = (file->f_flags & O_NONBLOCK); 
-
-
-       if(dma == NULL || (dma->s) == NULL) 
-               return -ENXIO;
-
-       if (dma->mmapped || !dma->opened)
-               return -ENXIO;
-
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-
-       if (! (dma->open_mode  & FMODE_READ))
-                return -ENXIO;
-
-       if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-       if(!(dma->started)){             
-               COMM          ("first read")
-                    
-               dma->writeptr = hwp;
-               dma->readptr = hwp;
-               dma->started = 1;
-       }
-
-       while (count > 0) {
-               cnt = rme96xx_getispace(dma,hwp);               
-               cnt>>=dma->formatshift;
-               cnt*=dma->inchannels;
-
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt != 0) {
-                       
-                       if (rme96xx_copytouser(dma,buffer,cnt,hop))
-                               return ret ? ret : -EFAULT;
-                       
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-                       if (count == 0) return ret;
-               }
-               if (file->f_flags & O_NONBLOCK)
-                       return ret ? ret : -EAGAIN;
-               
-               if ((hwp - dma->readptr) <= 0) {
-                       interruptible_sleep_on(&(dma->wait));
-                       
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-               }                       
-               hwp = rme96xx_gethwptr(dma->s,exact);
-
-       }; /* count > 0 */
-
-       return ret;
-}
-
-static int rm96xx_mmap(struct file *file, struct vm_area_struct *vma) {
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       rme96xx_info* s = dma->s;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-
-       if (vma->vm_pgoff != 0) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > RME96xx_DMA_MAX_SIZE) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-
-
-       if (vma->vm_flags & VM_WRITE) {
-               if (!s->started) rme96xx_startcard(s,1);
-
-               if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-                       unlock_kernel();
-                       return -EAGAIN;
-               }
-       } 
-       else if (vma->vm_flags & VM_READ) {
-               if (!s->started) rme96xx_startcard(s,1);
-               if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-                       unlock_kernel();
-                       return -EAGAIN;
-               }
-       } else  {
-               unlock_kernel();
-               return -EINVAL;
-       }
-
-
-/* this is the mapping */
-       vma->vm_flags &= ~VM_IO;
-       dma->mmapped = 1;
-       unlock_kernel();
-       return 0;
-}
-
-static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       rme96xx_info* s = dma->s;
-       unsigned int mask = 0;
-       unsigned int hwp,cnt;
-
-        DBG(printk("rme96xx poll_wait ...\n"));
-       VALIDATE_STATE(s);
-
-       if (!s->started) {
-                 mask |= POLLOUT | POLLWRNORM;
-       }
-       poll_wait(file, &dma->wait, wait);
-
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-        DBG(printk("rme96xx poll: ..cnt %d > %d\n",cnt,s->fragsize));  
-
-       cnt = rme96xx_getispace(dma,hwp);
-
-       if (file->f_mode & FMODE_READ) 
-            if (cnt > 0)
-                 mask |= POLLIN | POLLRDNORM;
-
-
-
-       cnt = rme96xx_getospace(dma,hwp);
-
-       if (file->f_mode & FMODE_WRITE) 
-            if (cnt > 0)
-                 mask |= POLLOUT | POLLWRNORM;
-
-
-//        printk("rme96xx poll_wait ...%d > %d\n",rme96xx_getospace(dma,hwp),rme96xx_getispace(dma,hwp));
-
-       return mask;
-}
-
-
-static struct file_operations rme96xx_audio_fops = {
-       .owner   = THIS_MODULE,
-       .read    = rme96xx_read,
-       .write   = rme96xx_write,
-       .poll    = rme96xx_poll,
-       .ioctl   = rme96xx_ioctl,  
-       .mmap    = rm96xx_mmap,
-       .open    = rme96xx_open,  
-       .release = rme96xx_release 
-};
-
-static int rme96xx_mixer_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       rme96xx_info *s;
-
-       COMM  ("mixer open");
-
-       nonseekable_open(inode, file);
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, rme96xx_info, devs);
-               if (s->mixer== minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-
-       COMM                       ("mixer opened")
-       return 0;
-}
-
-static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       rme96xx_info *s = (rme96xx_info *)file->private_data;
-       u32 status;
-       int spdifrate;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       status = readl(s->iobase + RME96xx_status_register);
-       /* hack to convert rev 1.5 SPDIF rate to "crystalrate" format   HP 20020201 */
-       rme96xx_spdif_sample_rate(s,&spdifrate);
-       status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F);
-
-       VALIDATE_STATE(s);
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               rme_mixer mixer;
-               if (copy_from_user(&mixer,argp,sizeof(mixer)))
-                       return -EFAULT;
-               
-               mixer.devnr &= RME96xx_MASK_DEVS;
-               if (mixer.devnr >= devices)
-                       mixer.devnr = devices-1;
-               if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) {
-                       /* modify only if device not open */
-                       if (mixer.o_offset < 0)
-                               mixer.o_offset = 0;
-                       if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD)
-                               mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1;
-                       if (mixer.i_offset < 0)
-                               mixer.i_offset = 0;
-                       if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD)
-                               mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1;
-                       s->dma[mixer.devnr].outoffset = mixer.o_offset;
-                       s->dma[mixer.devnr].inoffset = mixer.i_offset;
-               }
-
-               mixer.o_offset = s->dma[mixer.devnr].outoffset;
-               mixer.i_offset = s->dma[mixer.devnr].inoffset;
-
-               return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0;
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               return put_user(status, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE3) {
-               u32 control;
-               if (copy_from_user(&control,argp,sizeof(control)))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_WRITE) {
-                       s->control_register &= ~RME96xx_mixer_allowed;
-                       s->control_register |= control & RME96xx_mixer_allowed;
-                       writel(control,s->iobase + RME96xx_control_register);
-               }
-
-            return put_user(s->control_register, p);
-       }
-       return -1;
-}
-
-
-
-static int rme96xx_mixer_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static /*const*/ struct file_operations rme96xx_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .ioctl   = rme96xx_mixer_ioctl,
-       .open    = rme96xx_mixer_open,
-       .release = rme96xx_mixer_release,
-};
diff --git a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h
deleted file mode 100644 (file)
index 7a3c188..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-
-Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-   HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-   HP20020201 completed?
-
-A text/graphic control panel (rmectrl/xrmectrl) is available from
-   http://gige.xdv.org/pages/soft/pages/rme
-*/
-
-
-#ifndef AFMT_S32_BLOCKED
-#define AFMT_S32_BLOCKED 0x0000400
-#endif
-
-/* AFMT_S16_BLOCKED not yet supported */
-#ifndef AFMT_S16_BLOCKED 
-#define AFMT_S16_BLOCKED 0x0000800
-#endif
-
-
-typedef struct rme_status {
-       unsigned int irq:1;
-       unsigned int lockmask:3;     /* ADAT input PLLs locked */
-                                    /*   100=ADAT1, 010=ADAT2, 001=ADAT3 */
-       unsigned int sr48:1;         /* sample rate: 0=44.1/88.2 1=48/96 kHz */
-       unsigned int wclock:1;       /* 1=wordclock used */
-       unsigned int bufpoint:10;
-       unsigned int syncmask:3;     /* ADAT input in sync with system clock */
-                                    /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */
-       unsigned int doublespeed:1;  /* sample rate: 0=44.1/48 1=88.2/96 kHz */
-       unsigned int tc_busy:1;
-       unsigned int tc_out:1;
-       unsigned int crystalrate:3;  /* spdif input sample rate: */
-                                    /*   000=64kHz, 100=88.2kHz, 011=96kHz */
-                                    /*   111=32kHz, 110=44.1kHz, 101=48kHz */
-       unsigned int spdif_error:1;  /* 1=no spdif lock */
-       unsigned int bufid:1;
-       unsigned int tc_valid:1;     /* 1=timecode input detected */
-       unsigned int spdif_read:1;
-} rme_status_t;
-
-
-/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */
-typedef struct rme_control {
-       unsigned int start:1;
-       unsigned int latency:3;      /* buffer size / latency [samples]: */
-                                    /*   0=64 ... 7=8192 */
-       unsigned int master:1;       /* W: clock mode: 1=master 0=slave/auto */
-       unsigned int ie:1;
-       unsigned int sr48:1;         /* samplerate 0=44.1/88.2, 1=48/96 kHz */
-       unsigned int spare:1;
-       unsigned int doublespeed:1;  /* double speed 0=44.1/48, 1=88.2/96 Khz */
-       unsigned int pro:1;          /* W: SPDIF-OUT 0=consumer, 1=professional */
-       unsigned int emphasis:1;     /* W: SPDIF-OUT emphasis 0=off, 1=on */
-       unsigned int dolby:1;        /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */
-       unsigned int opt_out:1;      /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */
-       unsigned int wordclock:1;    /* W: use Wordclock as sync (overwrites master) */
-        unsigned int spdif_in:2;     /* W: SPDIF-IN: */
-                                     /*    00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */
-       unsigned int sync_ref:2;     /* W: preferred sync-source in autosync */
-                                     /*    00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-       unsigned int spdif_reset:1;
-       unsigned int spdif_select:1;
-       unsigned int spdif_clock:1;
-       unsigned int spdif_write:1;
-       unsigned int adat1_cd:1;     /* W: Rev 1.5+: if set, internal CD connector carries ADAT */
-} rme_ctrl_t;
-
-
-typedef struct _rme_mixer {
-       int i_offset;
-       int o_offset;
-       int devnr;
-       int spare[8];
-} rme_mixer;
-
index 75e54f6f638a1d8395195033bede7a19a7106e9c..733b014ec7d1637a50954b46ff64b6bd662241e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sb_audio.c
+ * sound/oss/sb_audio.c
  *
  * Audio routines for Sound Blaster compatible cards.
  *
index 35bab6e2f998a7f87442c99168715630750681ed..bbe5b7596d0e1167b321281da38a15ab70cde29d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sb_common.c
+ * sound/oss/sb_common.c
  *
  * Common routines for Sound Blaster compatible cards.
  *
index ed3bd0640ffd4ecbd2967e456bdcca9509b6ec4e..2e3bc045cabaf67d35a0d00d981dbba1e3df5866 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sb_dsp.c
+ * sound/oss/sb_midi.c
  *
  * The low level driver for the Sound Blaster DS chips.
  *
index ccb21d48d42c5f4c41208e7fb767220a95d18c99..238e2cf44b082bb1b702a3065baed77172d0c1b0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sb_mixer.c
+ * sound/oss/sb_mixer.c
  *
  * The low level mixer driver for the Sound Blaster compatible cards.
  */
index ab74426157ba7a185b4a9f81598b206e4ac82388..4b9425f085e36aae5e4747c9ede5a173b20d97a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sb_mixer.h
+ * sound/oss/sb_mixer.h
  * 
  * Definitions for the SB Pro and SB16 mixers
  */
index 6815c30e0bc1be68fd9589040b167499b5b2cde5..5c215f787ca9340e5cb2ad33da47c9658bb2dfcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sequencer.c
+ * sound/oss/sequencer.c
  *
  * The sequencer personality manager.
  */
@@ -16,7 +16,6 @@
  */
 #include <linux/kmod.h>
 #include <linux/spinlock.h>
-#define SEQUENCER_C
 #include "sound_config.h"
 
 #include "midi_ctrl.h"
@@ -157,6 +156,7 @@ void seq_copy_to_input(unsigned char *event_rec, int len)
        wake_up(&midi_sleeper);
        spin_unlock_irqrestore(&lock,flags);
 }
+EXPORT_SYMBOL(seq_copy_to_input);
 
 static void sequencer_midi_input(int dev, unsigned char data)
 {
@@ -206,6 +206,7 @@ void seq_input_event(unsigned char *event_rec, int len)
        }
        seq_copy_to_input(event_rec, len);
 }
+EXPORT_SYMBOL(seq_input_event);
 
 int sequencer_write(int dev, struct file *file, const char __user *buf, int count)
 {
@@ -1554,6 +1555,7 @@ void sequencer_timer(unsigned long dummy)
 {
        seq_startplay();
 }
+EXPORT_SYMBOL(sequencer_timer);
 
 int note_to_freq(int note_num)
 {
@@ -1587,6 +1589,7 @@ int note_to_freq(int note_num)
 
        return note_freq;
 }
+EXPORT_SYMBOL(note_to_freq);
 
 unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
                 int vibrato_cents)
@@ -1640,19 +1643,12 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
        else
                return (base_freq * amount) / 10000;    /* Bend up */
 }
-
+EXPORT_SYMBOL(compute_finetune);
 
 void sequencer_init(void)
 {
-       /* drag in sequencer_syms.o */
-       {
-               extern char sequencer_syms_symbol;
-               sequencer_syms_symbol = 0;
-       }
-
        if (sequencer_ok)
                return;
-       MIDIbuf_init();
        queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
        if (queue == NULL)
        {
@@ -1668,6 +1664,7 @@ void sequencer_init(void)
        }
        sequencer_ok = 1;
 }
+EXPORT_SYMBOL(sequencer_init);
 
 void sequencer_unload(void)
 {
diff --git a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c
deleted file mode 100644 (file)
index 5d00879..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Exported symbols for sequencer driver.
- */
-
-#include <linux/module.h>
-
-char sequencer_syms_symbol;
-
-#include "sound_config.h"
-#include "sound_calls.h"
-
-EXPORT_SYMBOL(note_to_freq);
-EXPORT_SYMBOL(compute_finetune);
-EXPORT_SYMBOL(seq_copy_to_input);
-EXPORT_SYMBOL(seq_input_event);
-EXPORT_SYMBOL(sequencer_init);
-EXPORT_SYMBOL(sequencer_timer);
-
-EXPORT_SYMBOL(sound_timer_init);
-EXPORT_SYMBOL(sound_timer_interrupt);
-EXPORT_SYMBOL(sound_timer_syncinterval);
-
-/* Tuning */
-
-#define _SEQUENCER_C_
-#include "tuning.h"
-
-EXPORT_SYMBOL(cent_tuning);
-EXPORT_SYMBOL(semitone_tuning);
diff --git a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c
deleted file mode 100644 (file)
index 3f32d46..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * sound/sgalaxy.c
- *
- * Low level driver for Aztech Sound Galaxy cards.
- * Copyright 1998 Artur Skawina <skawina@geocities.com>
- *
- * Supported cards:
- *    Aztech Sound Galaxy Waverider Pro 32 - 3D
- *    Aztech Sound Galaxy Washington 16
- *
- * Based on cs4232.c by Hannu Savolainen and Alan Cox.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added __init to sb_rst() and sb_cmd()
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-#include "ad1848.h"
-
-static void sleep( unsigned howlong )
-{
-       current->state   = TASK_INTERRUPTIBLE;
-       schedule_timeout(howlong);
-}
-
-#define DPORT 0x80
-
-/* Sound Blaster regs */
-
-#define SBDSP_RESET      0x6
-#define SBDSP_READ       0xA
-#define SBDSP_COMMAND    0xC
-#define SBDSP_STATUS     SBDSP_COMMAND
-#define SBDSP_DATA_AVAIL 0xE
-
-static int __init sb_rst(int base)
-{
-       int   i;
-   
-       outb( 1, base+SBDSP_RESET );     /* reset the DSP */
-       outb( 0, base+SBDSP_RESET );
-    
-       for ( i=0; i<500; i++ )          /* delay */
-               inb(DPORT);
-      
-       for ( i=0; i<100000; i++ )
-       {
-               if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
-                       break;
-       }
-
-       if ( inb( base+SBDSP_READ )!=0xAA )
-               return 0;
-
-       return 1;
-}
-
-static int __init sb_cmd( int base, unsigned char val )
-{
-       int  i;
-
-       for ( i=100000; i; i-- )
-       {
-               if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
-               {
-                       outb( val, base+SBDSP_COMMAND );
-                       break;
-               }
-       }
-       return i;      /* i>0 == success */
-}
-
-
-#define ai_sgbase    driver_use_1
-
-static int __init probe_sgalaxy( struct address_info *ai )
-{
-       struct resource *ports;
-       int n;
-
-       if (!request_region(ai->io_base, 4, "WSS config")) {
-               printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-               return 0;
-       }
-
-       ports = request_region(ai->io_base + 4, 4, "ad1848");
-       if (!ports) {
-               printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-               release_region(ai->io_base, 4);
-               return 0;
-       }
-
-       if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) {
-               printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
-               release_region(ai->io_base + 4, 4);
-               release_region(ai->io_base, 4);
-               return 0;
-       }
-        
-       if (ad1848_detect(ports, NULL, ai->osp))
-               goto out;  /* The card is already active, check irq etc... */
-        
-       /* switch to MSS/WSS mode */
-   
-       sb_rst( ai->ai_sgbase );
-   
-       sb_cmd( ai->ai_sgbase, 9 );
-       sb_cmd( ai->ai_sgbase, 0 );
-
-       sleep( HZ/10 );
-
-out:
-       if (!probe_ms_sound(ai, ports)) {
-               release_region(ai->io_base + 4, 4);
-               release_region(ai->io_base, 4);
-               release_region(ai->ai_sgbase, 0x10);
-               return 0;
-       }
-
-       attach_ms_sound(ai, ports, THIS_MODULE);
-       n=ai->slots[0];
-       
-       if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
-               AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE );   /* Line-in */
-               AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH );  /* FM+Wavetable*/
-               AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD );     /* CD */
-       }
-       return 1;
-}
-
-static void __exit unload_sgalaxy( struct address_info *ai )
-{
-       unload_ms_sound( ai );
-       release_region( ai->ai_sgbase, 0x10 );
-}
-
-static struct address_info cfg;
-
-static int __initdata io       = -1;
-static int __initdata irq      = -1;
-static int __initdata dma      = -1;
-static int __initdata dma2     = -1;
-static int __initdata sgbase   = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(sgbase, int, 0);
-
-static int __init init_sgalaxy(void)
-{
-       cfg.io_base   = io;
-       cfg.irq       = irq;
-       cfg.dma       = dma;
-       cfg.dma2      = dma2;
-       cfg.ai_sgbase = sgbase;
-
-       if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
-               printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
-               return -EINVAL;
-       }
-
-       if ( probe_sgalaxy(&cfg) == 0 )
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit cleanup_sgalaxy(void)
-{
-       unload_sgalaxy(&cfg);
-}
-
-module_init(init_sgalaxy);
-module_exit(cleanup_sgalaxy);
-
-#ifndef MODULE
-static int __init setup_sgalaxy(char *str)
-{
-       /* io, irq, dma, dma2, sgbase */
-       int ints[6];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma2    = ints[4];
-       sgbase  = ints[5];
-
-       return 1;
-}
-
-__setup("sgalaxy=", setup_sgalaxy);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
deleted file mode 100644 (file)
index 8ea532d..0000000
+++ /dev/null
@@ -1,2792 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      sonicvibes.c  --  S3 Sonic Vibes audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.1998   0.1   Initial release
- *    10.05.1998   0.2   Fixed many bugs, esp. ADC rate calculation
- *                       First stab at a simple midi interface (no bells&whistles)
- *    13.05.1998   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                       set_dac_rate in the FMODE_WRITE case in sv_open
- *                       Fix hwptr out of bounds (now mpg123 works)
- *    14.05.1998   0.4   Don't allow excessive interrupt rates
- *    08.06.1998   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.1998   0.6   Do not include modversions.h
- *                       Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *    31.08.1998   0.7   Fix realplayer problems - dac.count issues
- *    10.12.1998   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.1999   0.10  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    05.04.1999   0.13  added code to sv_read and sv_write which should detect
- *                       lockups of the sound chip and revive it. This is basically
- *                       an ugly hack, but at least applications using this driver
- *                       won't hang forever. I don't know why these lockups happen,
- *                       it might well be the motherboard chipset (an early 486 PCI
- *                       board with ALI chipset), since every busmastering 100MB
- *                       ethernet card I've tried (Realtek 8139 and Macronix tulip clone)
- *                       exhibit similar behaviour (they work for a couple of packets
- *                       and then lock up and can be revived by ifconfig down/up).
- *    07.04.1999   0.14  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: dmaio hack might still be wrong on archs other than i386
- *    15.06.1999   0.15  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.16  Add pci_set_master
- *    03.08.1999   0.17  adapt to Linus' new __setup/__initcall
- *                       added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr"
- *    12.08.1999   0.18  module_init/__setup fixes
- *    24.08.1999   0.19  get rid of the dmaio kludge, replace with allocate_resource
- *    31.08.1999   0.20  add spin_lock_init
- *                       use new resource allocation to allocate DDMA IO space
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.21  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.22  More waitqueue races fixed
- *    01.12.1999   0.23  New argument to allocate_resource
- *    07.12.1999   0.24  More allocate_resource semantics change
- *    08.01.2000   0.25  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       use Martin Mares' pci_assign_resource
- *    07.02.2000   0.26  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.28  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.29  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    18.05.2001   0.30  PCI probing and error values cleaned up by Marcus
- *                       Meissner <mm@caldera.de>
- *    03.01.2003   0.31  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3             0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SONICVIBES
-#define PCI_DEVICE_ID_S3_SONICVIBES  0xca00
-#endif
-
-#define SV_MAGIC  ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES)
-
-#define SV_EXTENT_SB      0x10
-#define SV_EXTENT_ENH     0x10
-#define SV_EXTENT_SYNTH   0x4
-#define SV_EXTENT_MIDI    0x4
-#define SV_EXTENT_GAME    0x8
-#define SV_EXTENT_DMA     0x10
-
-/*
- * we are not a bridge and thus use a resource for DDMA that is used for bridges but
- * left empty for normal devices
- */
-#define RESOURCE_SB       0
-#define RESOURCE_ENH      1
-#define RESOURCE_SYNTH    2
-#define RESOURCE_MIDI     3
-#define RESOURCE_GAME     4
-#define RESOURCE_DDMA     7
-
-#define SV_MIDI_DATA      0
-#define SV_MIDI_COMMAND   1
-#define SV_MIDI_STATUS    1
-
-#define SV_DMA_ADDR0      0
-#define SV_DMA_ADDR1      1
-#define SV_DMA_ADDR2      2
-#define SV_DMA_ADDR3      3
-#define SV_DMA_COUNT0     4
-#define SV_DMA_COUNT1     5
-#define SV_DMA_COUNT2     6
-#define SV_DMA_MODE       0xb
-#define SV_DMA_RESET      0xd
-#define SV_DMA_MASK       0xf
-
-/*
- * DONT reset the DMA controllers unless you understand
- * the reset semantics. Assuming reset semantics as in
- * the 8237 does not work.
- */
-
-#define DMA_MODE_AUTOINIT 0x10
-#define DMA_MODE_READ     0x44    /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE    0x48    /* memory to I/O, no autoinit, increment, single mode */
-
-#define SV_CODEC_CONTROL  0
-#define SV_CODEC_INTMASK  1
-#define SV_CODEC_STATUS   2
-#define SV_CODEC_IADDR    4
-#define SV_CODEC_IDATA    5
-
-#define SV_CCTRL_RESET      0x80
-#define SV_CCTRL_INTADRIVE  0x20
-#define SV_CCTRL_WAVETABLE  0x08
-#define SV_CCTRL_REVERB     0x04
-#define SV_CCTRL_ENHANCED   0x01
-
-#define SV_CINTMASK_DMAA    0x01
-#define SV_CINTMASK_DMAC    0x04
-#define SV_CINTMASK_SPECIAL 0x08
-#define SV_CINTMASK_UPDOWN  0x40
-#define SV_CINTMASK_MIDI    0x80
-
-#define SV_CSTAT_DMAA       0x01
-#define SV_CSTAT_DMAC      0x04
-#define SV_CSTAT_SPECIAL    0x08
-#define SV_CSTAT_UPDOWN            0x40
-#define SV_CSTAT_MIDI      0x80
-
-#define SV_CIADDR_TRD       0x80
-#define SV_CIADDR_MCE       0x40
-
-/* codec indirect registers */
-#define SV_CIMIX_ADCINL     0x00
-#define SV_CIMIX_ADCINR     0x01
-#define SV_CIMIX_AUX1INL    0x02
-#define SV_CIMIX_AUX1INR    0x03
-#define SV_CIMIX_CDINL      0x04
-#define SV_CIMIX_CDINR      0x05
-#define SV_CIMIX_LINEINL    0x06
-#define SV_CIMIX_LINEINR    0x07
-#define SV_CIMIX_MICIN      0x08
-#define SV_CIMIX_SYNTHINL   0x0A
-#define SV_CIMIX_SYNTHINR   0x0B
-#define SV_CIMIX_AUX2INL    0x0C
-#define SV_CIMIX_AUX2INR    0x0D
-#define SV_CIMIX_ANALOGINL  0x0E
-#define SV_CIMIX_ANALOGINR  0x0F
-#define SV_CIMIX_PCMINL     0x10
-#define SV_CIMIX_PCMINR     0x11
-
-#define SV_CIGAMECONTROL    0x09
-#define SV_CIDATAFMT        0x12
-#define SV_CIENABLE         0x13
-#define SV_CIUPDOWN         0x14
-#define SV_CIREVISION       0x15
-#define SV_CIADCOUTPUT      0x16
-#define SV_CIDMAABASECOUNT1 0x18
-#define SV_CIDMAABASECOUNT0 0x19
-#define SV_CIDMACBASECOUNT1 0x1c
-#define SV_CIDMACBASECOUNT0 0x1d
-#define SV_CIPCMSR0         0x1e
-#define SV_CIPCMSR1         0x1f
-#define SV_CISYNTHSR0       0x20
-#define SV_CISYNTHSR1       0x21
-#define SV_CIADCCLKSOURCE   0x22
-#define SV_CIADCALTSR       0x23
-#define SV_CIADCPLLM        0x24
-#define SV_CIADCPLLN        0x25
-#define SV_CISYNTHPLLM      0x26
-#define SV_CISYNTHPLLN      0x27
-#define SV_CIUARTCONTROL    0x2a
-#define SV_CIDRIVECONTROL   0x2b
-#define SV_CISRSSPACE       0x2c
-#define SV_CISRSCENTER      0x2d
-#define SV_CIWAVETABLESRC   0x2e
-#define SV_CIANALOGPWRDOWN  0x30
-#define SV_CIDIGITALPWRDOWN 0x31
-
-
-#define SV_CIMIX_ADCSRC_CD     0x20
-#define SV_CIMIX_ADCSRC_DAC    0x40
-#define SV_CIMIX_ADCSRC_AUX2   0x60
-#define SV_CIMIX_ADCSRC_LINE   0x80
-#define SV_CIMIX_ADCSRC_AUX1   0xa0
-#define SV_CIMIX_ADCSRC_MIC    0xc0
-#define SV_CIMIX_ADCSRC_MIXOUT 0xe0
-#define SV_CIMIX_ADCSRC_MASK   0xe0
-
-#define SV_CFMT_STEREO     0x01
-#define SV_CFMT_16BIT      0x02
-#define SV_CFMT_MASK       0x03
-#define SV_CFMT_ASHIFT     0   
-#define SV_CFMT_CSHIFT     4
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define SV_CENABLE_PPE     0x4
-#define SV_CENABLE_RE      0x2
-#define SV_CENABLE_PE      0x1
-
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 2
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-/* --------------------------------------------------------------------- */
-
-struct sv_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of sonicvibes devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-       int dev_dmfm;
-
-       /* hardware resources */
-       unsigned long iosb, ioenh, iosynth, iomidi;  /* long for SPARC */
-       unsigned int iodmaa, iodmac, irq;
-
-        /* mixer stuff */
-        struct {
-                unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
-               unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-        } mix;
-
-       /* wave stuff */
-       unsigned int rateadc, ratedac;
-       unsigned char fmt, enable;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#if SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-static unsigned long wavetable_mem;
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
-static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmaa, u;
-
-       count--;
-       for (u = 4; u > 0; u--, addr >>= 8, io++)
-               outb(addr & 0xff, io);
-       for (u = 3; u > 0; u--, count >>= 8, io++)
-               outb(count & 0xff, io);
-#else /* DMABYTEIO */
-       count--;
-       outl(addr, s->iodmaa + SV_DMA_ADDR0);
-       outl(count, s->iodmaa + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-       outb(0x18, s->iodmaa + SV_DMA_MODE);
-}
-
-static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmac, u;
-
-       count >>= 1;
-       count--;
-       for (u = 4; u > 0; u--, addr >>= 8, io++)
-               outb(addr & 0xff, io);
-       for (u = 3; u > 0; u--, count >>= 8, io++)
-               outb(count & 0xff, io);
-#else /* DMABYTEIO */
-       count >>= 1;
-       count--;
-       outl(addr, s->iodmac + SV_DMA_ADDR0);
-       outl(count, s->iodmac + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-       outb(0x14, s->iodmac + SV_DMA_MODE);
-}
-
-static inline unsigned get_dmaa(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmaa+6, v = 0, u;
-
-       for (u = 3; u > 0; u--, io--) {
-               v <<= 8;
-               v |= inb(io);
-       }
-       return v + 1;
-#else /* DMABYTEIO */
-       return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1;
-#endif /* DMABYTEIO */
-}
-
-static inline unsigned get_dmac(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmac+6, v = 0, u;
-
-       for (u = 3; u > 0; u--, io--) {
-               v <<= 8;
-               v |= inb(io);
-       }
-       return (v + 1) << 1;
-#else /* DMABYTEIO */
-       return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
-#endif /* DMABYTEIO */
-}
-
-static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data)
-{
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(data, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-}
-
-static unsigned char rdindir(struct sv_state *s, unsigned char idx)
-{
-       unsigned char v;
-
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       v = inb(s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       return v;
-}
-
-static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR);
-       if (mask) {
-               s->fmt = inb(s->ioenh + SV_CODEC_IDATA);
-               udelay(10);
-       }
-       s->fmt = (s->fmt & mask) | data;
-       outb(s->fmt, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(0, s->ioenh + SV_CODEC_IADDR);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-}
-
-static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-}
-
-#define REFFREQUENCY  24576000
-#define ADCMULT 512
-#define FULLRATE 48000
-
-static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char r, m=0, n=0;
-       unsigned xm, xn, xr, xd, metric = ~0U;
-       /* the warnings about m and n used uninitialized are bogus and may safely be ignored */
-
-       if (rate < 625000/ADCMULT)
-               rate = 625000/ADCMULT;
-       if (rate > 150000000/ADCMULT)
-               rate = 150000000/ADCMULT;
-       /* slight violation of specs, needed for continuous sampling rates */
-       for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1);
-       for (xn = 3; xn < 35; xn++)
-               for (xm = 3; xm < 130; xm++) {
-                       xr = REFFREQUENCY/ADCMULT * xm / xn;
-                       xd = abs((signed)(xr - rate));
-                       if (xd < metric) {
-                               metric = xd;
-                               m = xm - 2;
-                               n = xn - 2;
-                       }
-               }
-       reg &= 0x3f;
-       spin_lock_irqsave(&s->lock, flags);
-       outb(reg, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(m, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(r | n, s->ioenh + SV_CODEC_IDATA);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-       return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7);
-}
-
-#if 0
-
-static unsigned getpll(struct sv_state *s, unsigned char reg)
-{
-       unsigned long flags;
-       unsigned char m, n;
-
-       reg &= 0x3f;
-       spin_lock_irqsave(&s->lock, flags);
-       outb(reg, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       m = inb(s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       n = inb(s->ioenh + SV_CODEC_IDATA);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-       return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7);
-}
-
-#endif
-
-static void set_dac_rate(struct sv_state *s, unsigned rate)
-{
-       unsigned div;
-       unsigned long flags;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-       div = (rate * 65536 + FULLRATE/2) / FULLRATE;
-       if (div > 65535)
-               div = 65535;
-       spin_lock_irqsave(&s->lock, flags);
-       wrindir(s, SV_CIPCMSR1, div >> 8);
-       wrindir(s, SV_CIPCMSR0, div);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->ratedac = (div * FULLRATE + 32768) / 65536;
-}
-
-static void set_adc_rate(struct sv_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned rate1, rate2, div;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-       rate1 = setpll(s, SV_CIADCPLLM, rate);
-       div = (48000 + rate/2) / rate;
-       if (div > 8)
-               div = 8;
-       rate2 = (48000 + div/2) / div;
-       spin_lock_irqsave(&s->lock, flags);
-       wrindir(s, SV_CIADCALTSR, (div-1) << 4);
-       if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) {
-               wrindir(s, SV_CIADCCLKSOURCE, 0x10);
-               s->rateadc = rate2;
-       } else {
-               wrindir(s, SV_CIADCCLKSOURCE, 0x00);
-               s->rateadc = rate1;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->enable &= ~SV_CENABLE_RE;
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE);
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE;
-               wrindir(s, SV_CIENABLE, s->enable);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-           && s->dma_adc.ready) {
-               s->enable |= SV_CENABLE_RE;
-               wrindir(s, SV_CIENABLE, s->enable);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct sv_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-
-/* DMAA is used for playback, DMAC is used for recording */
-
-static int prog_dmabuf(struct sv_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-       unsigned char fmt;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       fmt = s->fmt;
-       if (rec) {
-               s->enable &= ~SV_CENABLE_RE;
-               fmt >>= SV_CFMT_CSHIFT;
-       } else {
-               s->enable &= ~SV_CENABLE_PE;
-               fmt >>= SV_CFMT_ASHIFT;
-       }
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-       fmt &= SV_CFMT_MASK;
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-                       printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
-                              virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-               if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-                       printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
-                              virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) {
-               set_dmac(s, db->dmaaddr, db->numfrag << db->fragshift);
-               /* program enhanced mode registers */
-               wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8);
-               wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1);
-       } else {
-               set_dmaa(s, db->dmaaddr, db->numfrag << db->fragshift);
-               /* program enhanced mode registers */
-               wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8);
-               wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(struct sv_state *s)
-{
-       unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80;
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void sv_update_ptr(struct sv_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-               hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize;
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->enable &= ~SV_CENABLE_RE;
-                               wrindir(s, SV_CIENABLE, s->enable);
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize;
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               s->enable &= ~SV_CENABLE_PE;
-                               wrindir(s, SV_CIENABLE, s->enable);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-/* hold spinlock for the following! */
-static void sv_handle_midi(struct sv_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       wake = 0;
-       while (!(inb(s->iomidi+1) & 0x80)) {
-               ch = inb(s->iomidi);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->iomidi);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-static irqreturn_t sv_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct sv_state *s = (struct sv_state *)dev_id;
-       unsigned int intsrc;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inb(s->ioenh + SV_CODEC_STATUS);
-       if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI)))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       sv_update_ptr(s);
-       sv_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-static void sv_midi_timer(unsigned long data)
-{
-       struct sv_state *s = (struct sv_state *)data;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&s->lock, flags);
-       sv_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies+1;
-       add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != SV_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-
-static const struct {
-       unsigned left:5;
-       unsigned right:5;
-       unsigned type:3;
-       unsigned rec:3;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL,    SV_CIMIX_ADCINR,    MT_4,         0 },
-       [SOUND_MIXER_LINE1]  = { SV_CIMIX_AUX1INL,   SV_CIMIX_AUX1INR,   MT_5MUTE,     5 },
-       [SOUND_MIXER_CD]     = { SV_CIMIX_CDINL,     SV_CIMIX_CDINR,     MT_5MUTE,     1 },
-       [SOUND_MIXER_LINE]   = { SV_CIMIX_LINEINL,   SV_CIMIX_LINEINR,   MT_5MUTE,     4 },
-       [SOUND_MIXER_MIC]    = { SV_CIMIX_MICIN,     SV_CIMIX_ADCINL,    MT_4MUTEMONO, 6 },
-       [SOUND_MIXER_SYNTH]  = { SV_CIMIX_SYNTHINL,  SV_CIMIX_SYNTHINR,  MT_5MUTE,     2 },
-       [SOUND_MIXER_LINE2]  = { SV_CIMIX_AUX2INL,   SV_CIMIX_AUX2INR,   MT_5MUTE,     3 },
-       [SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE,     7 },
-       [SOUND_MIXER_PCM]    = { SV_CIMIX_PCMINL,    SV_CIMIX_PCMINR,    MT_6MUTE,     0 }
-};
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct sv_state *s, unsigned i, int *arg)
-{
-       unsigned long flags;
-       unsigned char l, r, rl, rr;
-
-       spin_lock_irqsave(&s->lock, flags);
-       l = rdindir(s, mixtable[i].left);
-       r = rdindir(s, mixtable[i].right);
-       spin_unlock_irqrestore(&s->lock, flags);
-       switch (mixtable[i].type) {
-       case MT_4:
-               r &= 0xf;
-               l &= 0xf;
-               rl = 10 + 6 * (l & 15);
-               rr = 10 + 6 * (r & 15);
-               break;
-
-       case MT_4MUTEMONO:
-               rl = 55 - 3 * (l & 15);
-               if (r & 0x10)
-                       rl += 45;
-               rr = rl;
-               r = l;
-               break;
-
-       case MT_5MUTE:
-       default:
-               rl = 100 - 3 * (l & 31);
-               rr = 100 - 3 * (r & 31);
-               break;
-                               
-       case MT_6MUTE:
-               rl = 100 - 3 * (l & 63) / 2;
-               rr = 100 - 3 * (r & 63) / 2;
-               break;
-       }
-       if (l & 0x80)
-               rl = 0;
-       if (r & 0x80)
-               rr = 0;
-       return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = 
-{
-       [SOUND_MIXER_RECLEV] = 1,
-       [SOUND_MIXER_LINE1]  = 2,
-       [SOUND_MIXER_CD]     = 3,
-       [SOUND_MIXER_LINE]   = 4,
-       [SOUND_MIXER_MIC]    = 5,
-       [SOUND_MIXER_SYNTH]  = 6,
-       [SOUND_MIXER_LINE2]  = 7,
-       [SOUND_MIXER_VOLUME] = 8,
-       [SOUND_MIXER_PCM]    = 9
-};
-
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static unsigned mixer_recmask(struct sv_state *s)
-{
-       unsigned long flags;
-       int i, j;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdindir(s, SV_CIMIX_ADCINL) >> 5;
-       spin_unlock_irqrestore(&s->lock, flags);
-       j &= 7;
-       for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++);
-       return 1 << i;
-}
-
-static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val;
-       unsigned char l, r, rl, rr;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "SonicVibes", sizeof(info.id));
-               strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "SonicVibes", sizeof(info.id));
-               strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
-               if (get_user(val, p))
-                       return -EFAULT;
-               spin_lock_irqsave(&s->lock, flags);
-               if (val & 1) {
-                       if (val & 2) {
-                               l = 4 - ((val >> 2) & 7);
-                               if (l & ~3)
-                                       l = 4;
-                               r = 4 - ((val >> 5) & 7);
-                               if (r & ~3)
-                                       r = 4;
-                               wrindir(s, SV_CISRSSPACE, l);
-                               wrindir(s, SV_CISRSCENTER, r);
-                       } else
-                               wrindir(s, SV_CISRSSPACE, 0x80);
-               }
-               l = rdindir(s, SV_CISRSSPACE);
-               r = rdindir(s, SV_CISRSCENTER);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (l & 0x80)
-                       return put_user(0, p);
-               return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, p);
-       }
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(mixer_recmask(s), p);
-                       
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].rec)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                       return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-                       if (!volidx[i])
-                               return -EINVAL;
-                       return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               i = hweight32(val);
-               if (i == 0)
-                       return 0; /*val = mixer_recmask(s);*/
-               else if (i > 1) 
-                       val &= ~mixer_recmask(s);
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (mixtable[i].rec)
-                               break;
-               }
-               if (i == SOUND_MIXER_NRDEVICES)
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5);
-               frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               r = (val >> 8) & 0xff;
-               if (mixtable[i].type == MT_4MUTEMONO)
-                       l = (r + l) / 2;
-               if (l > 100)
-                       l = 100;
-               if (r > 100)
-                       r = 100;
-               spin_lock_irqsave(&s->lock, flags);
-               switch (mixtable[i].type) {
-               case MT_4:
-                       if (l >= 10)
-                               l -= 10;
-                       if (r >= 10)
-                               r -= 10;
-                       frobindir(s, mixtable[i].left, 0xf0, l / 6);
-                       frobindir(s, mixtable[i].right, 0xf0, l / 6);
-                       break;
-
-               case MT_4MUTEMONO:
-                       rr = 0;
-                       if (l < 10)
-                               rl = 0x80;
-                       else {
-                               if (l >= 55) {
-                                       rr = 0x10;
-                                       l -= 45;
-                               }
-                               rl = (55 - l) / 3;
-                       }
-                       wrindir(s, mixtable[i].left, rl);
-                       frobindir(s, mixtable[i].right, ~0x10, rr);
-                       break;
-                       
-               case MT_5MUTE:
-                       if (l < 7)
-                               rl = 0x80;
-                       else
-                               rl = (100 - l) / 3;
-                       if (r < 7)
-                               rr = 0x80;
-                       else
-                               rr = (100 - r) / 3;
-                       wrindir(s, mixtable[i].left, rl);
-                       wrindir(s, mixtable[i].right, rr);
-                       break;
-                               
-               case MT_6MUTE:
-                       if (l < 6)
-                               rl = 0x80;
-                       else
-                               rl = (100 - l) * 2 / 3;
-                       if (r < 6)
-                               rr = 0x80;
-                       else
-                               rr = (100 - r) * 2 / 3;
-                       wrindir(s, mixtable[i].left, rl);
-                       wrindir(s, mixtable[i].right, rr);
-                       break;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-               if (!volidx[i])
-                       return -EINVAL;
-               s->mix.vol[volidx[i]-1] = val;
-               return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sv_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int sv_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations sv_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = sv_ioctl_mixdev,
-       .open           = sv_open_mixdev,
-       .release        = sv_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct sv_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK];
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "sv: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-#if 0
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               stop_adc(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                               /* program enhanced mode registers */
-                               wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1);
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-       }
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t sv_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-#if 0
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_dac.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               stop_dac(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                               /* program enhanced mode registers */
-                               wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1);
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 1))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 0))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int sv_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else 
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-                       else
-                               fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-                       else
-                               fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int sv_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned char fmtm = ~0, fmts = 0;
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (file->f_mode & FMODE_READ) {
-               fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               set_adc_rate(s, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               s->dma_dac.enabled = 1;
-               set_dac_rate(s, 8000);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = sv_read,
-       .write          = sv_write,
-       .poll           = sv_poll,
-       .ioctl          = sv_ioctl,
-       .mmap           = sv_mmap,
-       .open           = sv_open,
-       .release        = sv_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-       add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                      __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                      if (file->f_flags & O_NONBLOCK) {
-                              if (!ret)
-                                      ret = -EAGAIN;
-                              break;
-                      }
-                      schedule();
-                      if (signal_pending(current)) {
-                              if (!ret)
-                                      ret = -ERESTARTSYS;
-                              break;
-                      }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t sv_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       sv_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int sv_midi_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_midi == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL);
-               outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-               wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */
-               wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */
-               outb(0xff, s->iomidi+1); /* reset command */
-               outb(0x3f, s->iomidi+1); /* uart command */
-               if (!(inb(s->iomidi+1) & 0x80))
-                       inb(s->iomidi);
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies+1;
-               s->midi.timer.data = (unsigned long)s;
-               s->midi.timer.function = sv_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_midi_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               remove_wait_queue(&s->midi.owait, &wait);
-                               set_current_state(TASK_RUNNING);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG "sv: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-               del_timer(&s->midi.timer);              
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = sv_midi_read,
-       .write          = sv_midi_write,
-       .poll           = sv_midi_poll,
-       .open           = sv_midi_open,
-       .release        = sv_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned char op_offset[18] = {
-               0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-               0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-               0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-       };
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       struct dm_fm_voice v;
-       struct dm_fm_note n;
-       struct dm_fm_params p;
-       unsigned int io;
-       unsigned int regb;
-
-       switch (cmd) {          
-       case FM_IOCTL_RESET:
-               for (regb = 0xb0; regb < 0xb9; regb++) {
-                       outb(regb, s->iosynth);
-                       outb(0, s->iosynth+1);
-                       outb(regb, s->iosynth+2);
-                       outb(0, s->iosynth+3);
-               }
-               return 0;
-
-       case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-                       return -EFAULT;
-               if (n.voice >= 18)
-                       return -EINVAL;
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->iosynth+2;
-               } else {
-                       regb = n.voice;
-                       io = s->iosynth;
-               }
-               outb(0xa0 + regb, io);
-               outb(n.fnum & 0xff, io+1);
-               outb(0xb0 + regb, io);
-               outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-               return 0;
-
-       case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-                       return -EFAULT;
-               if (v.voice >= 18)
-                       return -EINVAL;
-               regb = op_offset[v.voice];
-               io = s->iosynth + ((v.op & 1) << 1);
-               outb(0x20 + regb, io);
-               outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-                    ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-               outb(0x40 + regb, io);
-               outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-               outb(0x60 + regb, io);
-               outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-               outb(0x80 + regb, io);
-               outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-               outb(0xe0 + regb, io);
-               outb(v.waveform & 0x7, io+1);
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->iosynth+2;
-               } else {
-                       regb = n.voice;
-                       io = s->iosynth;
-               }
-               outb(0xc0 + regb, io);
-               outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-                    (v.connection & 1), io+1);
-               return 0;
-               
-       case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void *__user )arg, sizeof(p)))
-                       return -EFAULT;
-               outb(0x08, s->iosynth);
-               outb((p.kbd_split & 1) << 6, s->iosynth+1);
-               outb(0xbd, s->iosynth);
-               outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-                    ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
-               return 0;
-
-       case FM_IOCTL_SET_OPL:
-               outb(4, s->iosynth+2);
-               outb(arg, s->iosynth+3);
-               return 0;
-
-       case FM_IOCTL_SET_MODE:
-               outb(5, s->iosynth+2);
-               outb(arg & 1, s->iosynth+3);
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int sv_dmfm_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_dmfm == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DMFM) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       /* init the stuff */
-       outb(1, s->iosynth);
-       outb(0x20, s->iosynth+1); /* enable waveforms */
-       outb(4, s->iosynth+2);
-       outb(0, s->iosynth+3);  /* no 4op enabled */
-       outb(5, s->iosynth+2);
-       outb(1, s->iosynth+3);  /* enable OPL3 */
-       s->open_mode |= FMODE_DMFM;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_dmfm_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned int regb;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~FMODE_DMFM;
-       for (regb = 0xb0; regb < 0xb9; regb++) {
-               outb(regb, s->iosynth);
-               outb(0, s->iosynth+1);
-               outb(regb, s->iosynth+2);
-               outb(0, s->iosynth+3);
-       }
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_dmfm_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = sv_dmfm_ioctl,
-       .open           = sv_dmfm_open,
-       .release        = sv_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int reverb[NR_DEVICE];
-
-#if 0
-static int wavetable[NR_DEVICE];
-#endif
-
-static unsigned int devindex;
-
-module_param_array(reverb, bool, NULL, 0);
-MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM");
-#if 0
-MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
-#endif
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("S3 SonicVibes Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 }
-};
-
-#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
-                                (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit sv_register_gameport(struct sv_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, SV_EXTENT_GAME, "S3 SonicVibes Gameport")) {
-               printk(KERN_ERR "sv: gameport io ports are in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "sv: can not allocate memory for gameport\n");
-               release_region(io_port, SV_EXTENT_GAME);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "S3 SonicVibes Gameport");
-       gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void sv_unregister_gameport(struct sv_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, SV_EXTENT_GAME);
-       }
-}
-#else
-static inline int sv_register_gameport(struct sv_state *s, int io_port) { return -ENOSYS; }
-static inline void sv_unregister_gameport(struct sv_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
-               struct sv_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-       int gpio;
-       char *ddmaname;
-       unsigned ddmanamelen;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-
-       if (!RSRCISIOREGION(pcidev, RESOURCE_SB) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_ENH) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_MIDI) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_GAME))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-       if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) {
-               printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-       /* try to allocate a DDMA resource if not already available */
-       if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) {
-               pcidev->resource[RESOURCE_DDMA].start = 0;
-               pcidev->resource[RESOURCE_DDMA].end = 2*SV_EXTENT_DMA-1;
-               pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO;
-               ddmanamelen = strlen(sv_ddma_name)+1;
-               if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL)))
-                       return -1;
-               memcpy(ddmaname, sv_ddma_name, ddmanamelen);
-               pcidev->resource[RESOURCE_DDMA].name = ddmaname;
-               if (pci_assign_resource(pcidev, RESOURCE_DDMA)) {
-                       pcidev->resource[RESOURCE_DDMA].name = NULL;
-                       kfree(ddmaname);
-                       printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
-                       return -EBUSY;
-               }
-       }
-       if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "sv: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct sv_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = SV_MAGIC;
-       s->dev = pcidev;
-       s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
-       s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
-       s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
-       s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
-       s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
-       s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
-       gpio = pci_resource_start(pcidev, RESOURCE_GAME);
-       pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9);  /* enable and use extended mode */
-       pci_write_config_dword(pcidev, 0x48, s->iodmac | 9);  /* enable */
-       printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n",
-              s->iosb, s->ioenh, s->iosynth, s->iomidi, gpio, s->iodmaa, s->iodmac);
-       s->irq = pcidev->irq;
-       
-       /* hack */
-       pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12);  /* wavetable base address */
-
-       ret = -EBUSY;
-       if (!request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
-               goto err_region5;
-       }
-       if (!request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA")) {
-               printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1);
-               goto err_region4;
-       }
-       if (!request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC")) {
-               printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1);
-               goto err_region3;
-       }
-       if (!request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
-               goto err_region2;
-       }
-       if (!request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
-               goto err_region1;
-       }
-
-       /* initialize codec registers */
-       outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */
-       udelay(50);
-       outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */
-       udelay(50);
-       outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */
-            | (reverb[devindex] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL);
-       inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */
-       wrindir(s, SV_CIDRIVECONTROL, 0);  /* drive current 16mA */
-       wrindir(s, SV_CIENABLE, s->enable = 0);  /* disable DMAA and DMAC */
-       outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK);
-       /* outb(0xff, s->iodmaa + SV_DMA_RESET); */
-       /* outb(0xff, s->iodmac + SV_DMA_RESET); */
-       inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-       wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */
-       wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */
-       wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */
-       setpll(s, SV_CIADCPLLM, 8000);
-       wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */
-       wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff);
-       wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
-       wrindir(s, SV_CIADCOUTPUT, 0);
-       /* request irq */
-       if ((ret=request_irq(s->irq,sv_interrupt,IRQF_SHARED,"S3 SonicVibes",s))) {
-               printk(KERN_ERR "sv: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n",
-              s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev3;
-       }
-       if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) {
-               ret = s->dev_dmfm;
-               goto err_dev4;
-       }
-       pci_set_master(pcidev);  /* enable bus mastering */
-       /* initialize the chips */
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-       /* register gameport */
-       sv_register_gameport(s, gpio);
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_dev4:
-       unregister_sound_midi(s->dev_midi);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "sv: cannot register misc device\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->iosynth, SV_EXTENT_SYNTH);
- err_region1:
-       release_region(s->iomidi, SV_EXTENT_MIDI);
- err_region2:
-       release_region(s->iodmac, SV_EXTENT_DMA);
- err_region3:
-       release_region(s->iodmaa, SV_EXTENT_DMA);
- err_region4:
-       release_region(s->ioenh, SV_EXTENT_ENH);
- err_region5:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit sv_remove(struct pci_dev *dev)
-{
-       struct sv_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-       outb(~0, s->ioenh + SV_CODEC_INTMASK);  /* disable ints */
-       synchronize_irq(s->irq);
-       inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-       wrindir(s, SV_CIENABLE, 0);     /* disable DMAA and DMAC */
-       /*outb(0, s->iodmaa + SV_DMA_RESET);*/
-       /*outb(0, s->iodmac + SV_DMA_RESET);*/
-       free_irq(s->irq, s);
-       sv_unregister_gameport(s);
-       release_region(s->iodmac, SV_EXTENT_DMA);
-       release_region(s->iodmaa, SV_EXTENT_DMA);
-       release_region(s->ioenh, SV_EXTENT_ENH);
-       release_region(s->iomidi, SV_EXTENT_MIDI);
-       release_region(s->iosynth, SV_EXTENT_SYNTH);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       unregister_sound_special(s->dev_dmfm);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver sv_driver = {
-       .name           = "sonicvibes",
-       .id_table       = id_table,
-       .probe          = sv_probe,
-       .remove         = __devexit_p(sv_remove),
-};
-static int __init init_sonicvibes(void)
-{
-       printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n");
-#if 0
-       if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-               printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
-       return pci_register_driver(&sv_driver);
-}
-
-static void __exit cleanup_sonicvibes(void)
-{
-       printk(KERN_INFO "sv: unloading\n");
-       pci_unregister_driver(&sv_driver);
-       if (wavetable_mem)
-               free_pages(wavetable_mem, 20-PAGE_SHIFT);
-}
-
-module_init(init_sonicvibes);
-module_exit(cleanup_sonicvibes);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */
-
-static int __init sonicvibes_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-#if 0
-       if (get_option(&str, &reverb[nr_dev]) == 2)
-               (void)get_option(&str, &wavetable[nr_dev]);
-#else
-       (void)get_option(&str, &reverb[nr_dev]);
-#endif
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("sonicvibes=", sonicvibes_setup);
-
-#endif /* MODULE */
index 1ae07509664fb149fb18501f75f3bc91e4c483ae..87d8ad4a0340e763a018254886a1484c8696606a 100644 (file)
@@ -13,8 +13,6 @@ int DMAbuf_move_wrpointer(int dev, int l);
 void DMAbuf_init(int dev, int dma1, int dma2);
 void DMAbuf_deinit(int dev);
 int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
-int DMAbuf_open_dma (int dev);
-void DMAbuf_close_dma (int dev);
 void DMAbuf_inputintr(int dev);
 void DMAbuf_outputintr(int dev, int underflow_flag);
 struct dma_buffparms;
@@ -73,7 +71,6 @@ unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait);
 int MIDIbuf_avail(int dev);
 
 void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
-void MIDIbuf_init(void);
 
 
 /*     From soundcard.c        */
diff --git a/sound/oss/sound_syms.c b/sound/oss/sound_syms.c
deleted file mode 100644 (file)
index cb7c33f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *     The sound core exports the following symbols to the rest of
- *     modulespace.
- *
- *      (C) Copyright 1997      Alan Cox, Licensed under the GNU GPL
- *
- *     Thu May 27 1999 Andrew J. Kroll <ag784@freenet..buffalo..edu>
- *     left out exported symbol... fixed
- */
-
-#include <linux/module.h>
-#include "sound_config.h"
-#include "sound_calls.h"
-
-char sound_syms_symbol;
-
-EXPORT_SYMBOL(mixer_devs);
-EXPORT_SYMBOL(audio_devs);
-EXPORT_SYMBOL(num_mixers);
-EXPORT_SYMBOL(num_audiodevs);
-
-EXPORT_SYMBOL(midi_devs);
-EXPORT_SYMBOL(num_midis);
-EXPORT_SYMBOL(synth_devs);
-
-EXPORT_SYMBOL(sound_timer_devs);
-
-EXPORT_SYMBOL(sound_install_audiodrv);
-EXPORT_SYMBOL(sound_install_mixer);
-EXPORT_SYMBOL(sound_alloc_dma);
-EXPORT_SYMBOL(sound_free_dma);
-EXPORT_SYMBOL(sound_open_dma);
-EXPORT_SYMBOL(sound_close_dma);
-EXPORT_SYMBOL(sound_alloc_mididev);
-EXPORT_SYMBOL(sound_alloc_mixerdev);
-EXPORT_SYMBOL(sound_alloc_timerdev);
-EXPORT_SYMBOL(sound_alloc_synthdev);
-EXPORT_SYMBOL(sound_unload_audiodev);
-EXPORT_SYMBOL(sound_unload_mididev);
-EXPORT_SYMBOL(sound_unload_mixerdev);
-EXPORT_SYMBOL(sound_unload_timerdev);
-EXPORT_SYMBOL(sound_unload_synthdev);
-
-EXPORT_SYMBOL(load_mixer_volumes);
-
-EXPORT_SYMBOL(conf_printf);
-EXPORT_SYMBOL(conf_printf2);
-
-MODULE_DESCRIPTION("OSS Sound subsystem");
-MODULE_AUTHOR("Hannu Savolainen, et al.");
index bc2777dd2ef9c3884e20b6a35c7a1812dd2ecc7c..f0f0c19fbff7a75c4e5ad561d18ce9f970775e97 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sound_timer.c
+ * sound/oss/sound_timer.c
  */
 /*
  * Copyright (C) by Hannu Savolainen 1993-1997
@@ -76,6 +76,7 @@ void sound_timer_syncinterval(unsigned int new_usecs)
        tmr_ctr = 0;
        usecs_per_tmr = new_usecs;
 }
+EXPORT_SYMBOL(sound_timer_syncinterval);
 
 static void tmr_reset(void)
 {
@@ -300,6 +301,7 @@ void sound_timer_interrupt(void)
        }
        spin_unlock_irqrestore(&lock,flags);
 }
+EXPORT_SYMBOL(sound_timer_interrupt);
 
 void  sound_timer_init(struct sound_lowlev_timer *t, char *name)
 {
@@ -321,3 +323,5 @@ void  sound_timer_init(struct sound_lowlev_timer *t, char *name)
        strcpy(sound_timer.info.name, name);
        sound_timer_devs[n] = &sound_timer;
 }
+EXPORT_SYMBOL(sound_timer_init);
+
index 0860d678971567e52b3766752e6ab65cd73ed1c0..2344d09c7114fb4091d24f0fdfbc3d9da7c7bcff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/soundcard.c
+ * linux/sound/oss/soundcard.c
  *
  * Sound card driver for Linux
  *
@@ -107,6 +107,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
                mixer_vols[n].levels[i] = levels[i];
        return mixer_vols[n].levels;
 }
+EXPORT_SYMBOL(load_mixer_volumes);
 
 static int set_mixer_levels(void __user * arg)
 {
@@ -541,12 +542,6 @@ static int __init oss_init(void)
        int             err;
        int i, j;
        
-       /* drag in sound_syms.o */
-       {
-               extern char sound_syms_symbol;
-               sound_syms_symbol = 0;
-       }
-
 #ifdef CONFIG_PCI
        if(dmabug)
                isa_dma_bridge_buggy = dmabug;
@@ -614,6 +609,8 @@ static void __exit oss_cleanup(void)
 module_init(oss_init);
 module_exit(oss_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("OSS Sound subsystem");
+MODULE_AUTHOR("Hannu Savolainen, et al.");
 
 
 int sound_alloc_dma(int chn, char *deviceID)
@@ -627,6 +624,7 @@ int sound_alloc_dma(int chn, char *deviceID)
 
        return 0;
 }
+EXPORT_SYMBOL(sound_alloc_dma);
 
 int sound_open_dma(int chn, char *deviceID)
 {
@@ -642,6 +640,7 @@ int sound_open_dma(int chn, char *deviceID)
        dma_alloc_map[chn] = DMA_MAP_BUSY;
        return 0;
 }
+EXPORT_SYMBOL(sound_open_dma);
 
 void sound_free_dma(int chn)
 {
@@ -652,6 +651,7 @@ void sound_free_dma(int chn)
        free_dma(chn);
        dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
 }
+EXPORT_SYMBOL(sound_free_dma);
 
 void sound_close_dma(int chn)
 {
@@ -661,6 +661,7 @@ void sound_close_dma(int chn)
        }
        dma_alloc_map[chn] = DMA_MAP_FREE;
 }
+EXPORT_SYMBOL(sound_close_dma);
 
 static void do_sequencer_timer(unsigned long dummy)
 {
@@ -714,6 +715,7 @@ void conf_printf(char *name, struct address_info *hw_config)
        printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf);
 
 void conf_printf2(char *name, int base, int irq, int dma, int dma2)
 {
@@ -734,3 +736,5 @@ void conf_printf2(char *name, int base, int irq, int dma, int dma2)
        printk("\n");
 #endif
 }
+EXPORT_SYMBOL(conf_printf2);
+
index 9ed5211c3168156f05f8d0f9e89d4191c9f48c2e..51f2fa615413af605e314edf071263f534585473 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sscape.c
+ * sound/oss/sscape.c
  *
  * Low level driver for Ensoniq SoundScape
  *
index c9d04518b1722e95e93fc8c832a89f8df4ea084e..107534477a2f4937fd0a308be70d9f10fb46016b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/sys_timer.c
+ * sound/oss/sys_timer.c
  *
  * The default timer for the Level 2 sequencer interface
  * Uses the (1/HZ sec) timer of kernel.
index d1f1f154dcce5617d869489211f07baa637dd0b1..e04169e8e3f86be4a9460cd53589b2a49c241c70 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/trix.c
+ * sound/oss/trix.c
  *
  * Low level driver for the MediaTrix AudioTrix Pro
  * (MT-0002-PC Control Chip)
index 858e1fe6c618ceda29d1e79ca23964735418bae8..a73e3dd39f9a558bee683e1de5316a3e1329d9ef 100644 (file)
@@ -1,13 +1,11 @@
-#ifdef SEQUENCER_C
-
-unsigned short semitone_tuning[24] = 
+static unsigned short semitone_tuning[24] =
 {
 /*   0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, 
 /*   8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, 
 /*  16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
 };
 
-unsigned short cent_tuning[100] =
+static unsigned short cent_tuning[100] =
 {
 /*   0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, 
 /*   8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, 
@@ -23,7 +21,3 @@ unsigned short cent_tuning[100] =
 /*  88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, 
 /*  96 */ 10570, 10576, 10582, 10589
 };
-#else
-extern unsigned short semitone_tuning[24];
-extern unsigned short cent_tuning[100];
-#endif
index a3d75baf6df84a1642549a77ec2a2fc2b21e8d7a..8e18b6e25818f365c123a5fc5d7868e56bc0a9bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/uart401.c
+ * sound/oss/uart401.c
  *
  * MPU-401 UART driver (formerly uart401_midi.c)
  *
index 74ae75f9e2dc40e132a6b5e65a9fd68014698c30..501d3e654a67ba2e66849fad9cddb3945752bb50 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/uart6850.c
+ * sound/oss/uart6850.c
  *
  *
  * Copyright (C) by Hannu Savolainen 1993-1997
index a7ef04fab075b1a7bd7dd7e377d26f1555380f8e..d952b2264da1da46fc0cb70e4e7228b0cf0f4817 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sound/v_midi.c
+ * sound/oss/v_midi.c
  *
  * The low level driver for the Sound Blaster DS chips.
  *
index 22d26624b34a040687a27a6591da33fe69caee7b..59a2f28eb5a5a8bb1e7fb6ecc36f7c964c1b8612 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/waveartist.c
+ * linux/sound/oss/waveartist.c
  *
  * The low level driver for the RWA010 Rockwell Wave Artist
  * codec chip used in the Rebel.com NetWinder.
index 2033fb87b2478abd1721d9510483c274ef7b55fe..dac4ca910d951070e789edfe6a13ee1964ba4764 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/sound/waveartist.h
+ * linux/sound/oss/waveartist.h
  *
  * def file for Rockwell RWA010 chip set, as installed in Rebel.com NetWinder
  */
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
deleted file mode 100644 (file)
index 1dec395..0000000
+++ /dev/null
@@ -1,3554 +0,0 @@
-/*  -*- linux-c -*-
- *
- * sound/wavfront.c
- *
- * A Linux driver for Turtle Beach WaveFront Series (Maui, Tropez, Tropez Plus)
- *
- * This driver supports the onboard wavetable synthesizer (an ICS2115),
- * including patch, sample and program loading and unloading, conversion
- * of GUS patches during loading, and full user-level access to all
- * WaveFront commands. It tries to provide semi-intelligent patch and
- * sample management as well.
- *
- * It also provides support for the ICS emulation of an MPU-401.  Full
- * support for the ICS emulation's "virtual MIDI mode" is provided in
- * wf_midi.c.
- *
- * Support is also provided for the Tropez Plus' onboard FX processor,
- * a Yamaha YSS225. Currently, code exists to configure the YSS225,
- * and there is an interface allowing tweaking of any of its memory
- * addresses. However, I have been unable to decipher the logical
- * positioning of the configuration info for various effects, so for
- * now, you just get the YSS225 in the same state as Turtle Beach's
- * "SETUPSND.EXE" utility leaves it.
- *
- * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co],
- * This chip also controls the configuration of the card: the wavefront
- * synth is logical unit 4.
- *
- *
- * Supported devices:
- *
- *   /dev/dsp                      - using cs4232+ad1848 modules, OSS compatible
- *   /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible
- *   /dev/synth00                  - raw synth interface
- * 
- **********************************************************************
- *
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * Some portions of this file are taken from work that is
- * copyright (C) by Hannu Savolainen 1993-1996
- *
- * Although the relevant code here is all new, the handling of
- * sample/alias/multi- samples is entirely based on a driver by Matt
- * Martin and Rutger Nijlunsing which demonstrated how to get things
- * to work correctly. The GUS patch loading code has been almost
- * unaltered by me, except to fit formatting and function names in the
- * rest of the file. Many thanks to them.
- *
- * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
- * driver, and answering a few questions while this one was developed.
- *
- * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their
- * complete lack of help in developing this driver, and in particular
- * for their utter silence in response to questions about undocumented
- * aspects of configuring a WaveFront soundcard, particularly the
- * effects processor.
- *
- * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added some __init and __initdata to entries in yss225.c
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/syscalls.h>
-#include <linux/ioport.h>    
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-
-#include <linux/delay.h>
-
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME        "WaveFront MIDI"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-/* Compile-time control of the extent to which OSS is supported.
-
-   I consider /dev/sequencer to be an anachronism, but given its
-   widespread usage by various Linux MIDI software, it seems worth
-   offering support to it if it's not too painful. Instead of using
-   /dev/sequencer, I recommend:
-
-     for synth programming and patch loading: /dev/synthNN
-     for kernel-synchronized MIDI sequencing: the ALSA sequencer
-     for direct MIDI control: /dev/midiNN
-
-   I have never tried static compilation into the kernel. The #if's
-   for this are really just notes to myself about what the code is
-   for.
-*/
-
-#define OSS_SUPPORT_SEQ            0x1  /* use of /dev/sequencer */
-#define OSS_SUPPORT_STATIC_INSTALL 0x2  /* static compilation into kernel */
-
-#define OSS_SUPPORT_LEVEL          0x1  /* just /dev/sequencer for now */
-
-#if    OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-static int (*midi_load_patch) (int devno, int format, const char __user *addr,
-                              int offs, int count, int pmgr_flag) = NULL;
-#endif /* OSS_SUPPORT_SEQ */
-
-/* if WF_DEBUG not defined, no run-time debugging messages will
-   be available via the debug flag setting. Given the current
-   beta state of the driver, this will remain set until a future 
-   version.
-*/
-
-#define WF_DEBUG 1
-
-#ifdef WF_DEBUG
-
-/* Thank goodness for gcc's preprocessor ... */
-
-#define DPRINT(cond, format, args...) \
-       if ((dev.debug & (cond)) == (cond)) { \
-            printk (KERN_DEBUG LOGNAME format, ## args); \
-       }
-#else
-#define DPRINT(cond, format, args...)
-#endif
-
-#define LOGNAME "WaveFront: "
-
-/* bitmasks for WaveFront status port value */
-
-#define STAT_RINTR_ENABLED     0x01
-#define STAT_CAN_READ          0x02
-#define STAT_INTR_READ         0x04
-#define STAT_WINTR_ENABLED     0x10
-#define STAT_CAN_WRITE         0x20
-#define STAT_INTR_WRITE                0x40
-
-/*** Module-accessible parameters ***************************************/
-
-static int wf_raw;     /* we normally check for "raw state" to firmware
-                          loading. if set, then during driver loading, the
-                          state of the board is ignored, and we reset the
-                          board and load the firmware anyway.
-                       */
-                  
-static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
-                         whatever state it is when the driver is loaded.
-                         The default is to download the microprogram and
-                         associated coefficients to set it up for "default"
-                         operation, whatever that means.
-                      */
-
-static int debug_default;  /* you can set this to control debugging
-                             during driver loading. it takes any combination
-                             of the WF_DEBUG_* flags defined in
-                             wavefront.h
-                          */
-
-/* XXX this needs to be made firmware and hardware version dependent */
-
-static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
-                                                   version of the WaveFront OS
-                                                 */
-
-static int wait_polls = 2000; /* This is a number of tries we poll the
-                                status register before resorting to sleeping.
-                                WaveFront being an ISA card each poll takes
-                                about 1.2us. So before going to
-                                sleep we wait up to 2.4ms in a loop.
-                            */
-
-static int sleep_length = HZ/100; /* This says how long we're going to
-                                    sleep between polls.
-                                    10ms sounds reasonable for fast response.
-                                 */
-
-static int sleep_tries = 50;       /* Wait for status 0.5 seconds total. */
-
-static int reset_time = 2; /* hundreths of a second we wait after a HW reset for
-                             the expected interrupt.
-                          */
-
-static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
-                                    checks on-board RAM.
-                                 */
-
-static int osrun_time = 10;  /* time in seconds we wait for the OS to
-                               start running.
-                            */
-
-module_param(wf_raw, int, 0);
-module_param(fx_raw, int, 0);
-module_param(debug_default, int, 0);
-module_param(wait_polls, int, 0);
-module_param(sleep_length, int, 0);
-module_param(sleep_tries, int, 0);
-module_param(ospath, charp, 0);
-module_param(reset_time, int, 0);
-module_param(ramcheck_time, int, 0);
-module_param(osrun_time, int, 0);
-
-/***************************************************************************/
-
-/* Note: because this module doesn't export any symbols, this really isn't
-   a global variable, even if it looks like one. I was quite confused by
-   this when I started writing this as a (newer) module -- pbd.
-*/
-
-struct wf_config {
-       int devno;            /* device number from kernel */
-       int irq;              /* "you were one, one of the few ..." */
-       int base;             /* low i/o port address */
-
-#define mpu_data_port    base 
-#define mpu_command_port base + 1 /* write semantics */
-#define mpu_status_port  base + 1 /* read semantics */
-#define data_port        base + 2 
-#define status_port      base + 3 /* read semantics */
-#define control_port     base + 3 /* write semantics  */
-#define block_port       base + 4 /* 16 bit, writeonly */
-#define last_block_port  base + 6 /* 16 bit, writeonly */
-
-       /* FX ports. These are mapped through the ICS2115 to the YS225.
-          The ICS2115 takes care of flipping the relevant pins on the
-          YS225 so that access to each of these ports does the right
-          thing. Note: these are NOT documented by Turtle Beach.
-       */
-
-#define fx_status       base + 8 
-#define fx_op           base + 8 
-#define fx_lcr          base + 9 
-#define fx_dsp_addr     base + 0xa
-#define fx_dsp_page     base + 0xb 
-#define fx_dsp_lsb      base + 0xc 
-#define fx_dsp_msb      base + 0xd 
-#define fx_mod_addr     base + 0xe
-#define fx_mod_data     base + 0xf 
-
-       volatile int irq_ok;               /* set by interrupt handler */
-        volatile int irq_cnt;              /* ditto */
-       int opened;                        /* flag, holds open(2) mode */
-       char debug;                        /* debugging flags */
-       int freemem;                       /* installed RAM, in bytes */ 
-
-       int synth_dev;                     /* devno for "raw" synth */
-       int mididev;                       /* devno for internal MIDI */
-       int ext_mididev;                   /* devno for external MIDI */ 
-        int fx_mididev;                    /* devno for FX MIDI interface */
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       int oss_dev;                      /* devno for OSS sequencer synth */
-#endif /* OSS_SUPPORT_SEQ */
-
-       char fw_version[2];                /* major = [0], minor = [1] */
-       char hw_version[2];                /* major = [0], minor = [1] */
-       char israw;                        /* needs Motorola microcode */
-       char has_fx;                       /* has FX processor (Tropez+) */
-       char prog_status[WF_MAX_PROGRAM];  /* WF_SLOT_* */
-       char patch_status[WF_MAX_PATCH];   /* WF_SLOT_* */
-       char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
-       int samples_used;                  /* how many */
-       char interrupts_on;                /* h/w MPU interrupts enabled ? */
-       char rom_samples_rdonly;           /* can we write on ROM samples */
-       wait_queue_head_t interrupt_sleeper; 
-} dev;
-
-static DEFINE_SPINLOCK(lock);
-static int  detect_wffx(void);
-static int  wffx_ioctl (wavefront_fx_info *);
-static int  wffx_init (void);
-
-static int wavefront_delete_sample (int sampnum);
-static int wavefront_find_free_sample (void);
-
-/* From wf_midi.c */
-
-extern int  virtual_midi_enable  (void);
-extern int  virtual_midi_disable (void);
-extern int  detect_wf_mpu (int, int);
-extern int  install_wf_mpu (void);
-extern int  uninstall_wf_mpu (void);
-
-typedef struct {
-       int cmd;
-       char *action;
-       unsigned int read_cnt;
-       unsigned int write_cnt;
-       int need_ack;
-} wavefront_command;
-
-static struct {
-       int errno;
-       const char *errstr;
-} wavefront_errors[] = {
-       { 0x01, "Bad sample number" },
-       { 0x02, "Out of sample memory" },
-       { 0x03, "Bad patch number" },
-       { 0x04, "Error in number of voices" },
-       { 0x06, "Sample load already in progress" },
-       { 0x0B, "No sample load request pending" },
-       { 0x0E, "Bad MIDI channel number" },
-       { 0x10, "Download Record Error" },
-       { 0x80, "Success" },
-       { 0 }
-};
-
-#define NEEDS_ACK 1
-
-static wavefront_command wavefront_commands[] = {
-       { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
-       { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
-       { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
-       { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
-       { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
-       { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
-       { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
-       { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
-       { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
-       { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
-       { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
-       { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
-       { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
-       { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
-       { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
-       { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
-       { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
-       { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
-       { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
-       { WFC_DOWNLOAD_SAMPLE, "download sample",
-         0, WF_SAMPLE_BYTES, NEEDS_ACK },
-       { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
-       { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
-         0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
-       { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
-
-       /* This command requires a variable number of bytes to be written.
-          There is a hack in wavefront_cmd() to support this. The actual
-          count is passed in as the read buffer ptr, cast appropriately.
-          Ugh.
-       */
-
-       { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
-
-       /* This one is a hack as well. We just read the first byte of the
-          response, don't fetch an ACK, and leave the rest to the 
-          calling function. Ugly, ugly, ugly.
-       */
-
-       { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
-       { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
-         0, WF_ALIAS_BYTES, NEEDS_ACK },
-       { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
-       { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
-       { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
-       { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
-       { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
-       { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
-       { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
-       { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
-       { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
-       { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
-         NEEDS_ACK},
-       { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
-       { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
-         0, 1, NEEDS_ACK },
-       { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
-       { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
-         32, 0, 0 },
-       { WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
-       { 0x00 }
-};
-
-static const char *
-wavefront_errorstr (int errnum)
-
-{
-       int i;
-
-       for (i = 0; wavefront_errors[i].errstr; i++) {
-               if (wavefront_errors[i].errno == errnum) {
-                       return wavefront_errors[i].errstr;
-               }
-       }
-
-       return "Unknown WaveFront error";
-}
-
-static wavefront_command *
-wavefront_get_command (int cmd) 
-
-{
-       int i;
-
-       for (i = 0; wavefront_commands[i].cmd != 0; i++) {
-               if (cmd == wavefront_commands[i].cmd) {
-                       return &wavefront_commands[i];
-               }
-       }
-
-       return (wavefront_command *) 0;
-}
-
-static inline int
-wavefront_status (void) 
-
-{
-       return inb (dev.status_port);
-}
-
-static int
-wavefront_wait (int mask)
-
-{
-       int i;
-
-       for (i = 0; i < wait_polls; i++)
-               if (wavefront_status() & mask)
-                       return 1;
-
-       for (i = 0; i < sleep_tries; i++) {
-
-               if (wavefront_status() & mask) {
-                       set_current_state(TASK_RUNNING);
-                       return 1;
-               }
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(sleep_length);
-               if (signal_pending(current))
-                       break;
-       }
-
-       set_current_state(TASK_RUNNING);
-       return 0;
-}
-
-static int
-wavefront_read (void)
-
-{
-       if (wavefront_wait (STAT_CAN_READ))
-               return inb (dev.data_port);
-
-       DPRINT (WF_DEBUG_DATA, "read timeout.\n");
-
-       return -1;
-}
-
-static int
-wavefront_write (unsigned char data)
-
-{
-       if (wavefront_wait (STAT_CAN_WRITE)) {
-               outb (data, dev.data_port);
-               return 0;
-       }
-
-       DPRINT (WF_DEBUG_DATA, "write timeout.\n");
-
-       return -1;
-}
-
-static int
-wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
-
-{
-       int ack;
-       int i;
-       int c;
-       wavefront_command *wfcmd;
-
-       if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
-               printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n",
-                       cmd);
-               return 1;
-       }
-
-       /* Hack to handle the one variable-size write command. See
-          wavefront_send_multisample() for the other half of this
-          gross and ugly strategy.
-       */
-
-       if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
-               wfcmd->write_cnt = (unsigned int) rbuf;
-               rbuf = NULL;
-       }
-
-       DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
-                              cmd, wfcmd->action, wfcmd->read_cnt,
-                              wfcmd->write_cnt, wfcmd->need_ack);
-    
-       if (wavefront_write (cmd)) { 
-               DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
-                                                    "0x%x [%s].\n",
-                                                    cmd, wfcmd->action);
-               return 1;
-       } 
-
-       if (wfcmd->write_cnt > 0) {
-               DPRINT (WF_DEBUG_DATA, "writing %d bytes "
-                                       "for 0x%x\n",
-                                       wfcmd->write_cnt, cmd);
-
-               for (i = 0; i < wfcmd->write_cnt; i++) {
-                       if (wavefront_write (wbuf[i])) {
-                               DPRINT (WF_DEBUG_IO, "bad write for byte "
-                                                     "%d of 0x%x [%s].\n",
-                                                     i, cmd, wfcmd->action);
-                               return 1;
-                       }
-
-                       DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
-                                               i, wbuf[i]);
-               }
-       }
-
-       if (wfcmd->read_cnt > 0) {
-               DPRINT (WF_DEBUG_DATA, "reading %d ints "
-                                       "for 0x%x\n",
-                                       wfcmd->read_cnt, cmd);
-
-               for (i = 0; i < wfcmd->read_cnt; i++) {
-
-                       if ((c = wavefront_read()) == -1) {
-                               DPRINT (WF_DEBUG_IO, "bad read for byte "
-                                                     "%d of 0x%x [%s].\n",
-                                                     i, cmd, wfcmd->action);
-                               return 1;
-                       }
-
-                       /* Now handle errors. Lots of special cases here */
-           
-                       if (c == 0xff) { 
-                               if ((c = wavefront_read ()) == -1) {
-                                       DPRINT (WF_DEBUG_IO, "bad read for "
-                                                             "error byte at "
-                                                             "read byte %d "
-                                                             "of 0x%x [%s].\n",
-                                                             i, cmd,
-                                                             wfcmd->action);
-                                       return 1;
-                               }
-
-                               /* Can you believe this madness ? */
-
-                               if (c == 1 &&
-                                   wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
-                                       rbuf[0] = WF_ST_EMPTY;
-                                       return (0);
-
-                               } else if (c == 3 &&
-                                          wfcmd->cmd == WFC_UPLOAD_PATCH) {
-
-                                       return 3;
-
-                               } else if (c == 1 &&
-                                          wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
-
-                                       return 1;
-
-                               } else {
-
-                                       DPRINT (WF_DEBUG_IO, "error %d (%s) "
-                                                             "during "
-                                                             "read for byte "
-                                                             "%d of 0x%x "
-                                                             "[%s].\n",
-                                                             c,
-                                                             wavefront_errorstr (c),
-                                                             i, cmd,
-                                                             wfcmd->action);
-                                       return 1;
-
-                               }
-               
-               } else {
-                               rbuf[i] = c;
-                       }
-                       
-                       DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
-               }
-       }
-       
-       if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
-
-               DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
-
-               /* Some commands need an ACK, but return zero instead
-                  of the standard value.
-               */
-           
-               if ((ack = wavefront_read()) == 0) {
-                       ack = WF_ACK;
-               }
-       
-               if (ack != WF_ACK) {
-                       if (ack == -1) {
-                               DPRINT (WF_DEBUG_IO, "cannot read ack for "
-                                                     "0x%x [%s].\n",
-                                                     cmd, wfcmd->action);
-                               return 1;
-               
-                       } else {
-                               int err = -1; /* something unknown */
-
-                               if (ack == 0xff) { /* explicit error */
-                   
-                                       if ((err = wavefront_read ()) == -1) {
-                                               DPRINT (WF_DEBUG_DATA,
-                                                       "cannot read err "
-                                                       "for 0x%x [%s].\n",
-                                                       cmd, wfcmd->action);
-                                       }
-                               }
-                               
-                               DPRINT (WF_DEBUG_IO, "0x%x [%s] "
-                                       "failed (0x%x, 0x%x, %s)\n",
-                                       cmd, wfcmd->action, ack, err,
-                                       wavefront_errorstr (err));
-                               
-                               return -err;
-                       }
-               }
-               
-               DPRINT (WF_DEBUG_DATA, "ack received "
-                                       "for 0x%x [%s]\n",
-                                       cmd, wfcmd->action);
-       } else {
-
-               DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
-                                      "ACK (%d,%d,%d)\n",
-                                      cmd, wfcmd->action, wfcmd->read_cnt,
-                                      wfcmd->write_cnt, wfcmd->need_ack);
-       }
-
-       return 0;
-       
-}
-\f
-/***********************************************************************
-WaveFront: data munging   
-
-Things here are weird. All data written to the board cannot 
-have its most significant bit set. Any data item with values 
-potentially > 0x7F (127) must be split across multiple bytes.
-
-Sometimes, we need to munge numeric values that are represented on
-the x86 side as 8-32 bit values. Sometimes, we need to munge data
-that is represented on the x86 side as an array of bytes. The most
-efficient approach to handling both cases seems to be to use 2
-different functions for munging and 2 for de-munging. This avoids
-weird casting and worrying about bit-level offsets.
-
-**********************************************************************/
-
-static 
-unsigned char *
-munge_int32 (unsigned int src,
-            unsigned char *dst,
-            unsigned int dst_size)
-{
-       int i;
-
-       for (i = 0;i < dst_size; i++) {
-               *dst = src & 0x7F;  /* Mask high bit of LSB */
-               src = src >> 7;     /* Rotate Right 7 bits  */
-                                   /* Note: we leave the upper bits in place */ 
-
-               dst++;
-       };
-       return dst;
-};
-
-static int 
-demunge_int32 (unsigned char* src, int src_size)
-
-{
-       int i;
-       int outval = 0;
-       
-       for (i = src_size - 1; i >= 0; i--) {
-               outval=(outval<<7)+src[i];
-       }
-
-       return outval;
-};
-
-static 
-unsigned char *
-munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
-
-{
-       int i;
-       unsigned int last = dst_size / 2;
-
-       for (i = 0; i < last; i++) {
-               *dst++ = src[i] & 0x7f;
-               *dst++ = src[i] >> 7;
-       }
-       return dst;
-}
-
-static 
-unsigned char *
-demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
-
-{
-       int i;
-       unsigned char *end = src + src_bytes;
-    
-       end = src + src_bytes;
-
-       /* NOTE: src and dst *CAN* point to the same address */
-
-       for (i = 0; src != end; i++) {
-               dst[i] = *src++;
-               dst[i] |= (*src++)<<7;
-       }
-
-       return dst;
-}
-\f
-/***********************************************************************
-WaveFront: sample, patch and program management.
-***********************************************************************/
-
-static int
-wavefront_delete_sample (int sample_num)
-
-{
-       unsigned char wbuf[2];
-       int x;
-
-       wbuf[0] = sample_num & 0x7f;
-       wbuf[1] = sample_num >> 7;
-
-       if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
-               dev.sample_status[sample_num] = WF_ST_EMPTY;
-       }
-
-       return x;
-}
-
-static int
-wavefront_get_sample_status (int assume_rom)
-
-{
-       int i;
-       unsigned char rbuf[32], wbuf[32];
-       unsigned int    sc_real, sc_alias, sc_multi;
-
-       /* check sample status */
-    
-       if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) {
-               printk (KERN_WARNING LOGNAME "cannot request sample count.\n");
-               return -1;
-       } 
-    
-       sc_real = sc_alias = sc_multi = dev.samples_used = 0;
-    
-       for (i = 0; i < WF_MAX_SAMPLE; i++) {
-       
-               wbuf[0] = i & 0x7f;
-               wbuf[1] = i >> 7;
-
-               if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
-                       printk (KERN_WARNING LOGNAME
-                               "cannot identify sample "
-                               "type of slot %d\n", i);
-                       dev.sample_status[i] = WF_ST_EMPTY;
-                       continue;
-               }
-
-               dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
-
-               if (assume_rom) {
-                       dev.sample_status[i] |= WF_SLOT_ROM;
-               }
-
-               switch (rbuf[0] & WF_ST_MASK) {
-               case WF_ST_SAMPLE:
-                       sc_real++;
-                       break;
-               case WF_ST_MULTISAMPLE:
-                       sc_multi++;
-                       break;
-               case WF_ST_ALIAS:
-                       sc_alias++;
-                       break;
-               case WF_ST_EMPTY:
-                       break;
-
-               default:
-                       printk (KERN_WARNING LOGNAME "unknown sample type for "
-                               "slot %d (0x%x)\n", 
-                               i, rbuf[0]);
-               }
-
-               if (rbuf[0] != WF_ST_EMPTY) {
-                       dev.samples_used++;
-               } 
-       }
-
-       printk (KERN_INFO LOGNAME
-               "%d samples used (%d real, %d aliases, %d multi), "
-               "%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi,
-               WF_MAX_SAMPLE - dev.samples_used);
-
-
-       return (0);
-
-}
-
-static int
-wavefront_get_patch_status (void)
-
-{
-       unsigned char patchbuf[WF_PATCH_BYTES];
-       unsigned char patchnum[2];
-       wavefront_patch *p;
-       int i, x, cnt, cnt2;
-
-       for (i = 0; i < WF_MAX_PATCH; i++) {
-               patchnum[0] = i & 0x7f;
-               patchnum[1] = i >> 7;
-
-               if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf,
-                                       patchnum)) == 0) {
-
-                       dev.patch_status[i] |= WF_SLOT_FILLED;
-                       p = (wavefront_patch *) patchbuf;
-                       dev.sample_status
-                               [p->sample_number|(p->sample_msb<<7)] |=
-                               WF_SLOT_USED;
-           
-               } else if (x == 3) { /* Bad patch number */
-                       dev.patch_status[i] = 0;
-               } else {
-                       printk (KERN_ERR LOGNAME "upload patch "
-                               "error 0x%x\n", x);
-                       dev.patch_status[i] = 0;
-                       return 1;
-               }
-       }
-
-       /* program status has already filled in slot_used bits */
-
-       for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
-               if (dev.patch_status[i] & WF_SLOT_FILLED) {
-                       cnt++;
-               }
-               if (dev.patch_status[i] & WF_SLOT_USED) {
-                       cnt2++;
-               }
-       
-       }
-       printk (KERN_INFO LOGNAME
-               "%d patch slots filled, %d in use\n", cnt, cnt2);
-
-       return (0);
-}
-
-static int
-wavefront_get_program_status (void)
-
-{
-       unsigned char progbuf[WF_PROGRAM_BYTES];
-       wavefront_program prog;
-       unsigned char prognum;
-       int i, x, l, cnt;
-
-       for (i = 0; i < WF_MAX_PROGRAM; i++) {
-               prognum = i;
-
-               if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf,
-                                       &prognum)) == 0) {
-
-                       dev.prog_status[i] |= WF_SLOT_USED;
-
-                       demunge_buf (progbuf, (unsigned char *) &prog,
-                                    WF_PROGRAM_BYTES);
-
-                       for (l = 0; l < WF_NUM_LAYERS; l++) {
-                               if (prog.layer[l].mute) {
-                                       dev.patch_status
-                                               [prog.layer[l].patch_number] |=
-                                               WF_SLOT_USED;
-                               }
-                       }
-               } else if (x == 1) { /* Bad program number */
-                       dev.prog_status[i] = 0;
-               } else {
-                       printk (KERN_ERR LOGNAME "upload program "
-                               "error 0x%x\n", x);
-                       dev.prog_status[i] = 0;
-               }
-       }
-
-       for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
-               if (dev.prog_status[i]) {
-                       cnt++;
-               }
-       }
-
-       printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt);
-
-       return (0);
-}
-
-static int
-wavefront_send_patch (wavefront_patch_info *header)
-
-{
-       unsigned char buf[WF_PATCH_BYTES+2];
-       unsigned char *bptr;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
-                                     header->number);
-
-       dev.patch_status[header->number] |= WF_SLOT_FILLED;
-
-       bptr = buf;
-       bptr = munge_int32 (header->number, buf, 2);
-       munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
-    
-       if (wavefront_cmd (WFC_DOWNLOAD_PATCH, NULL, buf)) {
-               printk (KERN_ERR LOGNAME "download patch failed\n");
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int
-wavefront_send_program (wavefront_patch_info *header)
-
-{
-       unsigned char buf[WF_PROGRAM_BYTES+1];
-       int i;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
-               header->number);
-
-       dev.prog_status[header->number] = WF_SLOT_USED;
-
-       /* XXX need to zero existing SLOT_USED bit for program_status[i]
-          where `i' is the program that's being (potentially) overwritten.
-       */
-    
-       for (i = 0; i < WF_NUM_LAYERS; i++) {
-               if (header->hdr.pr.layer[i].mute) {
-                       dev.patch_status[header->hdr.pr.layer[i].patch_number] |=
-                               WF_SLOT_USED;
-
-                       /* XXX need to mark SLOT_USED for sample used by
-                          patch_number, but this means we have to load it. Ick.
-                       */
-               }
-       }
-
-       buf[0] = header->number;
-       munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
-    
-       if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, NULL, buf)) {
-               printk (KERN_WARNING LOGNAME "download patch failed\n");        
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int
-wavefront_freemem (void)
-
-{
-       char rbuf[8];
-
-       if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, NULL)) {
-               printk (KERN_WARNING LOGNAME "can't get memory stats.\n");
-               return -1;
-       } else {
-               return demunge_int32 (rbuf, 4);
-       }
-}
-
-static int
-wavefront_send_sample (wavefront_patch_info *header,
-                      UINT16 __user *dataptr,
-                      int data_is_unsigned)
-
-{
-       /* samples are downloaded via a 16-bit wide i/o port
-          (you could think of it as 2 adjacent 8-bit wide ports
-          but its less efficient that way). therefore, all
-          the blocksizes and so forth listed in the documentation,
-          and used conventionally to refer to sample sizes,
-          which are given in 8-bit units (bytes), need to be
-          divided by 2.
-        */
-
-       UINT16 sample_short;
-       UINT32 length;
-       UINT16 __user *data_end = NULL;
-       unsigned int i;
-       const int max_blksize = 4096/2;
-       unsigned int written;
-       unsigned int blocksize;
-       int dma_ack;
-       int blocknum;
-       unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
-       unsigned char *shptr;
-       int skip = 0;
-       int initial_skip = 0;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
-                                     "type %d, %d bytes from %p\n",
-                                     header->size ? "" : "header ", 
-                                     header->number, header->subkey,
-                                     header->size,
-                                     header->dataptr);
-
-       if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
-               int x;
-
-               if ((x = wavefront_find_free_sample ()) < 0) {
-                       return -ENOMEM;
-               }
-               printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x);
-               header->number = x;
-       }
-
-       if (header->size) {
-
-               /* XXX it's a debatable point whether or not RDONLY semantics
-                  on the ROM samples should cover just the sample data or
-                  the sample header. For now, it only covers the sample data,
-                  so anyone is free at all times to rewrite sample headers.
-
-                  My reason for this is that we have the sample headers
-                  available in the WFB file for General MIDI, and so these
-                  can always be reset if needed. The sample data, however,
-                  cannot be recovered without a complete reset and firmware
-                  reload of the ICS2115, which is a very expensive operation.
-
-                  So, doing things this way allows us to honor the notion of
-                  "RESETSAMPLES" reasonably cheaply. Note however, that this
-                  is done purely at user level: there is no WFB parser in
-                  this driver, and so a complete reset (back to General MIDI,
-                  or theoretically some other configuration) is the
-                  responsibility of the user level library. 
-
-                  To try to do this in the kernel would be a little
-                  crazy: we'd need 158K of kernel space just to hold
-                  a copy of the patch/program/sample header data.
-               */
-
-               if (dev.rom_samples_rdonly) {
-                       if (dev.sample_status[header->number] & WF_SLOT_ROM) {
-                               printk (KERN_ERR LOGNAME "sample slot %d "
-                                       "write protected\n",
-                                       header->number);
-                               return -EACCES;
-                       }
-               }
-
-               wavefront_delete_sample (header->number);
-       }
-
-       if (header->size) {
-               dev.freemem = wavefront_freemem ();
-
-               if (dev.freemem < header->size) {
-                       printk (KERN_ERR LOGNAME
-                               "insufficient memory to "
-                               "load %d byte sample.\n",
-                               header->size);
-                       return -ENOMEM;
-               }
-       
-       }
-
-       skip = WF_GET_CHANNEL(&header->hdr.s);
-
-       if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
-               printk (KERN_ERR LOGNAME "channel selection only "
-                       "possible on 16-bit samples");
-               return -(EINVAL);
-       }
-
-       switch (skip) {
-       case 0:
-               initial_skip = 0;
-               skip = 1;
-               break;
-       case 1:
-               initial_skip = 0;
-               skip = 2;
-               break;
-       case 2:
-               initial_skip = 1;
-               skip = 2;
-               break;
-       case 3:
-               initial_skip = 2;
-               skip = 3;
-               break;
-       case 4:
-               initial_skip = 3;
-               skip = 4;
-               break;
-       case 5:
-               initial_skip = 4;
-               skip = 5;
-               break;
-       case 6:
-               initial_skip = 5;
-               skip = 6;
-               break;
-       }
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
-                                     "initial skip = %d, skip = %d\n",
-                                     WF_GET_CHANNEL (&header->hdr.s),
-                                     initial_skip, skip);
-    
-       /* Be safe, and zero the "Unused" bits ... */
-
-       WF_SET_CHANNEL(&header->hdr.s, 0);
-
-       /* adjust size for 16 bit samples by dividing by two.  We always
-          send 16 bits per write, even for 8 bit samples, so the length
-          is always half the size of the sample data in bytes.
-       */
-
-       length = header->size / 2;
-
-       /* the data we're sent has not been munged, and in fact, the
-          header we have to send isn't just a munged copy either.
-          so, build the sample header right here.
-       */
-
-       shptr = &sample_hdr[0];
-
-       shptr = munge_int32 (header->number, shptr, 2);
-
-       if (header->size) {
-               shptr = munge_int32 (length, shptr, 4);
-       }
-
-       /* Yes, a 4 byte result doesn't contain all of the offset bits,
-          but the offset only uses 24 bits.
-       */
-
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
-                            shptr, 4);
-       
-       /* This one is truly weird. What kind of weirdo decided that in
-          a system dominated by 16 and 32 bit integers, they would use
-          a just 12 bits ?
-       */
-       
-       shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
-       
-       /* Why is this nybblified, when the MSB is *always* zero ? 
-          Anyway, we can't take address of bitfield, so make a
-          good-faith guess at where it starts.
-       */
-       
-       shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
-                            shptr, 2);
-
-       if (wavefront_cmd (header->size ?
-                          WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
-                          NULL, sample_hdr)) {
-               printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n",
-                       header->size ? "" : "header ");
-               return -(EIO);
-       }
-
-       if (header->size == 0) {
-               goto sent; /* Sorry. Just had to have one somewhere */
-       }
-    
-       data_end = dataptr + length;
-
-       /* Do any initial skip over an unused channel's data */
-
-       dataptr += initial_skip;
-    
-       for (written = 0, blocknum = 0;
-            written < length; written += max_blksize, blocknum++) {
-       
-               if ((length - written) > max_blksize) {
-                       blocksize = max_blksize;
-               } else {
-                       /* round to nearest 16-byte value */
-                       blocksize = ((length-written+7)&~0x7);
-               }
-
-               if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
-                       printk (KERN_WARNING LOGNAME "download block "
-                               "request refused.\n");
-                       return -(EIO);
-               }
-
-               for (i = 0; i < blocksize; i++) {
-
-                       if (dataptr < data_end) {
-               
-                               __get_user (sample_short, dataptr);
-                               dataptr += skip;
-               
-                               if (data_is_unsigned) { /* GUS ? */
-
-                                       if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
-                       
-                                               /* 8 bit sample
-                                                resolution, sign
-                                                extend both bytes.
-                                               */
-                       
-                                               ((unsigned char*)
-                                                &sample_short)[0] += 0x7f;
-                                               ((unsigned char*)
-                                                &sample_short)[1] += 0x7f;
-                       
-                                       } else {
-                       
-                                               /* 16 bit sample
-                                                resolution, sign
-                                                extend the MSB.
-                                               */
-                       
-                                               sample_short += 0x7fff;
-                                       }
-                               }
-
-                       } else {
-
-                               /* In padding section of final block:
-
-                                  Don't fetch unsupplied data from
-                                  user space, just continue with
-                                  whatever the final value was.
-                               */
-                       }
-           
-                       if (i < blocksize - 1) {
-                               outw (sample_short, dev.block_port);
-                       } else {
-                               outw (sample_short, dev.last_block_port);
-                       }
-               }
-
-               /* Get "DMA page acknowledge", even though its really
-                  nothing to do with DMA at all.
-               */
-       
-               if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) {
-                       if (dma_ack == -1) {
-                               printk (KERN_ERR LOGNAME "upload sample "
-                                       "DMA ack timeout\n");
-                               return -(EIO);
-                       } else {
-                               printk (KERN_ERR LOGNAME "upload sample "
-                                       "DMA ack error 0x%x\n",
-                                       dma_ack);
-                               return -(EIO);
-                       }
-               }
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
-
-       /* Note, label is here because sending the sample header shouldn't
-          alter the sample_status info at all.
-       */
-
- sent:
-       return (0);
-}
-
-static int
-wavefront_send_alias (wavefront_patch_info *header)
-
-{
-       unsigned char alias_hdr[WF_ALIAS_BYTES];
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
-                                     "alias for %d\n",
-                                     header->number,
-                                     header->hdr.a.OriginalSample);
-    
-       munge_int32 (header->number, &alias_hdr[0], 2);
-       munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
-       munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
-                    &alias_hdr[4], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
-                    &alias_hdr[8], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
-                    &alias_hdr[12], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
-                    &alias_hdr[16], 4);
-       munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
-       munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
-
-       if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) {
-               printk (KERN_ERR LOGNAME "download alias failed.\n");
-               return -(EIO);
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
-
-       return (0);
-}
-
-static int
-wavefront_send_multisample (wavefront_patch_info *header)
-{
-       int i;
-       int num_samples;
-       unsigned char msample_hdr[WF_MSAMPLE_BYTES];
-
-       munge_int32 (header->number, &msample_hdr[0], 2);
-
-       /* You'll recall at this point that the "number of samples" value
-          in a wavefront_multisample struct is actually the log2 of the
-          real number of samples.
-       */
-
-       num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
-       msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
-                                     header->number,
-                                     header->hdr.ms.NumberOfSamples,
-                                     num_samples);
-
-       for (i = 0; i < num_samples; i++) {
-               DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
-                      i, header->hdr.ms.SampleNumber[i]);
-               munge_int32 (header->hdr.ms.SampleNumber[i],
-                    &msample_hdr[3+(i*2)], 2);
-       }
-    
-       /* Need a hack here to pass in the number of bytes
-          to be written to the synth. This is ugly, and perhaps
-          one day, I'll fix it.
-       */
-
-       if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE, 
-                          (unsigned char *) ((num_samples*2)+3),
-                          msample_hdr)) {
-               printk (KERN_ERR LOGNAME "download of multisample failed.\n");
-               return -(EIO);
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
-
-       return (0);
-}
-
-static int
-wavefront_fetch_multisample (wavefront_patch_info *header)
-{
-       int i;
-       unsigned char log_ns[1];
-       unsigned char number[2];
-       int num_samples;
-
-       munge_int32 (header->number, number, 2);
-    
-       if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
-               printk (KERN_ERR LOGNAME "upload multisample failed.\n");
-               return -(EIO);
-       }
-    
-       DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
-                               header->number, log_ns[0]);
-
-       header->hdr.ms.NumberOfSamples = log_ns[0];
-
-       /* get the number of samples ... */
-
-       num_samples = (1 << log_ns[0]);
-    
-       for (i = 0; i < num_samples; i++) {
-               s8 d[2];
-       
-               if ((d[0] = wavefront_read ()) == -1) {
-                       printk (KERN_ERR LOGNAME "upload multisample failed "
-                               "during sample loop.\n");
-                       return -(EIO);
-               }
-
-               if ((d[1] = wavefront_read ()) == -1) {
-                       printk (KERN_ERR LOGNAME "upload multisample failed "
-                               "during sample loop.\n");
-                       return -(EIO);
-               }
-       
-               header->hdr.ms.SampleNumber[i] =
-                       demunge_int32 ((unsigned char *) d, 2);
-       
-               DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
-                                       i, header->hdr.ms.SampleNumber[i]);
-       }
-
-       return (0);
-}
-
-
-static int
-wavefront_send_drum (wavefront_patch_info *header)
-
-{
-       unsigned char drumbuf[WF_DRUM_BYTES];
-       wavefront_drum *drum = &header->hdr.d;
-       int i;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
-               "note %d, patch = %d\n", 
-               header->number, drum->PatchNumber);
-
-       drumbuf[0] = header->number & 0x7f;
-
-       for (i = 0; i < 4; i++) {
-               munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
-       }
-
-       if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) {
-               printk (KERN_ERR LOGNAME "download drum failed.\n");
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int 
-wavefront_find_free_sample (void)
-
-{
-       int i;
-
-       for (i = 0; i < WF_MAX_SAMPLE; i++) {
-               if (!(dev.sample_status[i] & WF_SLOT_FILLED)) {
-                       return i;
-               }
-       }
-       printk (KERN_WARNING LOGNAME "no free sample slots!\n");
-       return -1;
-}
-
-static int 
-wavefront_find_free_patch (void)
-
-{
-       int i;
-
-       for (i = 0; i < WF_MAX_PATCH; i++) {
-               if (!(dev.patch_status[i] & WF_SLOT_FILLED)) {
-                       return i;
-               }
-       }
-       printk (KERN_WARNING LOGNAME "no free patch slots!\n");
-       return -1;
-}
-
-static int 
-log2_2048(int n)
-
-{
-       int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143,
-                  6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192,
-                  8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390,
-                  9510, 9626, 9738, 9845, 9949, 10049, 10146};
-       int i;
-
-       /* Returns 2048*log2(n) */
-
-       /* FIXME: this is like doing integer math
-          on quantum particles (RuN) */
-
-       i=0;
-       while(n>=32*256) {
-               n>>=8;
-               i+=2048*8;
-       }
-       while(n>=32) {
-               n>>=1;
-               i+=2048;
-       }
-       i+=tbl[n];
-       return(i);
-}
-
-static int
-wavefront_load_gus_patch (int devno, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag)
-{
-       struct patch_info guspatch;
-       wavefront_patch_info *samp, *pat, *prog;
-       wavefront_patch *patp;
-       wavefront_sample *sampp;
-       wavefront_program *progp;
-
-       int i,base_note;
-       long sizeof_patch;
-       int rc = -ENOMEM;
-
-       samp = kmalloc(3 * sizeof(wavefront_patch_info), GFP_KERNEL);
-       if (!samp)
-               goto free_fail;
-       pat = samp + 1;
-       prog = pat + 1;
-
-       /* Copy in the header of the GUS patch */
-
-       sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; 
-       if (copy_from_user(&((char *) &guspatch)[offs],
-                          &(addr)[offs], sizeof_patch - offs)) {
-               rc = -EFAULT;
-               goto free_fail;
-       }
-
-       if ((i = wavefront_find_free_patch ()) == -1) {
-               rc = -EBUSY;
-               goto free_fail;
-       }
-       pat->number = i;
-       pat->subkey = WF_ST_PATCH;
-       patp = &pat->hdr.p;
-
-       if ((i = wavefront_find_free_sample ()) == -1) {
-               rc = -EBUSY;
-               goto free_fail;
-       }
-       samp->number = i;
-       samp->subkey = WF_ST_SAMPLE;
-       samp->size = guspatch.len;
-       sampp = &samp->hdr.s;
-
-       prog->number = guspatch.instr_no;
-       progp = &prog->hdr.pr;
-
-       /* Setup the patch structure */
-
-       patp->amplitude_bias=guspatch.volume;
-       patp->portamento=0;
-       patp->sample_number= samp->number & 0xff;
-       patp->sample_msb= samp->number >> 8;
-       patp->pitch_bend= /*12*/ 0;
-       patp->mono=1;
-       patp->retrigger=1;
-       patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1;
-       patp->frequency_bias=0;
-       patp->restart=0;
-       patp->reuse=0;
-       patp->reset_lfo=1;
-       patp->fm_src2=0;
-       patp->fm_src1=WF_MOD_MOD_WHEEL;
-       patp->am_src=WF_MOD_PRESSURE;
-       patp->am_amount=127;
-       patp->fc1_mod_amount=0;
-       patp->fc2_mod_amount=0; 
-       patp->fm_amount1=0;
-       patp->fm_amount2=0;
-       patp->envelope1.attack_level=127;
-       patp->envelope1.decay1_level=127;
-       patp->envelope1.decay2_level=127;
-       patp->envelope1.sustain_level=127;
-       patp->envelope1.release_level=0;
-       patp->envelope2.attack_velocity=127;
-       patp->envelope2.attack_level=127;
-       patp->envelope2.decay1_level=127;
-       patp->envelope2.decay2_level=127;
-       patp->envelope2.sustain_level=127;
-       patp->envelope2.release_level=0;
-       patp->envelope2.attack_velocity=127;
-       patp->randomizer=0;
-
-       /* Program for this patch */
-
-       progp->layer[0].patch_number= pat->number; /* XXX is this right ? */
-       progp->layer[0].mute=1;
-       progp->layer[0].pan_or_mod=1;
-       progp->layer[0].pan=7;
-       progp->layer[0].mix_level=127  /* guspatch.volume */;
-       progp->layer[0].split_type=0;
-       progp->layer[0].split_point=0;
-       progp->layer[0].play_below=0;
-
-       for (i = 1; i < 4; i++) {
-               progp->layer[i].mute=0;
-       }
-
-       /* Sample data */
-
-       sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1);
-
-       for (base_note=0;
-            note_to_freq (base_note) < guspatch.base_note;
-            base_note++);
-
-       if ((guspatch.base_note-note_to_freq(base_note))
-           >(note_to_freq(base_note)-guspatch.base_note))
-               base_note++;
-
-       printk(KERN_DEBUG "ref freq=%d,base note=%d\n",
-              guspatch.base_freq,
-              base_note);
-
-       sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq)
-                               + base_note*171);
-       printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias);
-       sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0;
-       sampp->sampleStartOffset.Fraction=0;
-       sampp->sampleStartOffset.Integer=0;
-       sampp->loopStartOffset.Fraction=0;
-       sampp->loopStartOffset.Integer=guspatch.loop_start
-               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-       sampp->loopEndOffset.Fraction=0;
-       sampp->loopEndOffset.Integer=guspatch.loop_end
-               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-       sampp->sampleEndOffset.Fraction=0;
-       sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1);
-       sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0;
-       sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0;
-
-       /* Now ship it down */
-
-       wavefront_send_sample (samp,
-                              (unsigned short __user *) &(addr)[sizeof_patch],
-                              (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
-       wavefront_send_patch (pat);
-       wavefront_send_program (prog);
-
-       /* Now pan as best we can ... use the slave/internal MIDI device
-          number if it exists (since it talks to the WaveFront), or the
-          master otherwise.
-       */
-
-       if (dev.mididev > 0) {
-               midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
-                                      ((guspatch.panning << 4) > 127) ?
-                                      127 : (guspatch.panning << 4));
-       }
-       rc = 0;
-
-free_fail:
-       kfree(samp);
-       return rc;
-}
-
-static int
-wavefront_load_patch (const char __user *addr)
-
-
-{
-       wavefront_patch_info header;
-       
-       if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
-                           sizeof(wavefront_any))) {
-               printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
-               return -EFAULT;
-       }
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "download "
-                                     "Sample type: %d "
-                                     "Sample number: %d "
-                                     "Sample size: %d\n",
-                                     header.subkey,
-                                     header.number,
-                                     header.size);
-
-       switch (header.subkey) {
-       case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
-
-               if (copy_from_user((unsigned char *) &header.hdr.s,
-                                  (unsigned char __user *) header.hdrptr,
-                                  sizeof (wavefront_sample)))
-                       return -EFAULT;
-
-               return wavefront_send_sample (&header, header.dataptr, 0);
-
-       case WF_ST_MULTISAMPLE:
-
-               if (copy_from_user(&header.hdr.s, header.hdrptr,
-                                  sizeof(wavefront_multisample)))
-                       return -EFAULT;
-
-               return wavefront_send_multisample (&header);
-
-
-       case WF_ST_ALIAS:
-
-               if (copy_from_user(&header.hdr.a, header.hdrptr,
-                                  sizeof (wavefront_alias)))
-                       return -EFAULT;
-
-               return wavefront_send_alias (&header);
-
-       case WF_ST_DRUM:
-               if (copy_from_user(&header.hdr.d, header.hdrptr,
-                                  sizeof (wavefront_drum)))
-                       return -EFAULT;
-
-               return wavefront_send_drum (&header);
-
-       case WF_ST_PATCH:
-               if (copy_from_user(&header.hdr.p, header.hdrptr,
-                                  sizeof (wavefront_patch)))
-                       return -EFAULT;
-
-               return wavefront_send_patch (&header);
-
-       case WF_ST_PROGRAM:
-               if (copy_from_user(&header.hdr.pr, header.hdrptr,
-                                  sizeof (wavefront_program)))
-                       return -EFAULT;
-
-               return wavefront_send_program (&header);
-
-       default:
-               printk (KERN_ERR LOGNAME "unknown patch type %d.\n",
-                       header.subkey);
-               return -(EINVAL);
-       }
-
-       return 0;
-}
-\f
-/***********************************************************************
-WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces
-***********************************************************************/
-
-static void
-process_sample_hdr (UCHAR8 *buf)
-
-{
-       wavefront_sample s;
-       UCHAR8 *ptr;
-
-       ptr = buf;
-
-       /* The board doesn't send us an exact copy of a "wavefront_sample"
-          in response to an Upload Sample Header command. Instead, we 
-          have to convert the data format back into our data structure,
-          just as in the Download Sample command, where we have to do
-          something very similar in the reverse direction.
-       */
-
-       *((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
-
-       s.SampleResolution = *ptr & 0x3;
-       s.Loop = *ptr & 0x8;
-       s.Bidirectional = *ptr & 0x10;
-       s.Reverse = *ptr & 0x40;
-
-       /* Now copy it back to where it came from */
-
-       memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
-}
-
-static int
-wavefront_synth_control (int cmd, wavefront_control *wc)
-
-{
-       unsigned char patchnumbuf[2];
-       int i;
-
-       DPRINT (WF_DEBUG_CMD, "synth control with "
-               "cmd 0x%x\n", wc->cmd);
-
-       /* Pre-handling of or for various commands */
-
-       switch (wc->cmd) {
-       case WFC_DISABLE_INTERRUPTS:
-               printk (KERN_INFO LOGNAME "interrupts disabled.\n");
-               outb (0x80|0x20, dev.control_port);
-               dev.interrupts_on = 0;
-               return 0;
-
-       case WFC_ENABLE_INTERRUPTS:
-               printk (KERN_INFO LOGNAME "interrupts enabled.\n");
-               outb (0x80|0x40|0x20, dev.control_port);
-               dev.interrupts_on = 1;
-               return 0;
-
-       case WFC_INTERRUPT_STATUS:
-               wc->rbuf[0] = dev.interrupts_on;
-               return 0;
-
-       case WFC_ROMSAMPLES_RDONLY:
-               dev.rom_samples_rdonly = wc->wbuf[0];
-               wc->status = 0;
-               return 0;
-
-       case WFC_IDENTIFY_SLOT_TYPE:
-               i = wc->wbuf[0] | (wc->wbuf[1] << 7);
-               if (i <0 || i >= WF_MAX_SAMPLE) {
-                       printk (KERN_WARNING LOGNAME "invalid slot ID %d\n",
-                               i);
-                       wc->status = EINVAL;
-                       return 0;
-               }
-               wc->rbuf[0] = dev.sample_status[i];
-               wc->status = 0;
-               return 0;
-
-       case WFC_DEBUG_DRIVER:
-               dev.debug = wc->wbuf[0];
-               printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug);
-               return 0;
-
-       case WFC_FX_IOCTL:
-               wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]);
-               return 0;
-
-       case WFC_UPLOAD_PATCH:
-               munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2);
-               memcpy (wc->wbuf, patchnumbuf, 2);
-               break;
-
-       case WFC_UPLOAD_MULTISAMPLE:
-               /* multisamples have to be handled differently, and
-                  cannot be dealt with properly by wavefront_cmd() alone.
-               */
-               wc->status = wavefront_fetch_multisample
-                       ((wavefront_patch_info *) wc->rbuf);
-               return 0;
-
-       case WFC_UPLOAD_SAMPLE_ALIAS:
-               printk (KERN_INFO LOGNAME "support for sample alias upload "
-                       "being considered.\n");
-               wc->status = EINVAL;
-               return -EINVAL;
-       }
-
-       wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf);
-
-       /* Post-handling of certain commands.
-
-          In particular, if the command was an upload, demunge the data
-          so that the user-level doesn't have to think about it.
-       */
-
-       if (wc->status == 0) {
-               switch (wc->cmd) {
-                       /* intercept any freemem requests so that we know
-                          we are always current with the user-level view
-                          of things.
-                       */
-
-               case WFC_REPORT_FREE_MEMORY:
-                       dev.freemem = demunge_int32 (wc->rbuf, 4);
-                       break;
-
-               case WFC_UPLOAD_PATCH:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
-                       break;
-
-               case WFC_UPLOAD_PROGRAM:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
-                       break;
-
-               case WFC_UPLOAD_EDRUM_PROGRAM:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
-                       break;
-
-               case WFC_UPLOAD_SAMPLE_HEADER:
-                       process_sample_hdr (wc->rbuf);
-                       break;
-
-               case WFC_UPLOAD_SAMPLE_ALIAS:
-                       printk (KERN_INFO LOGNAME "support for "
-                               "sample aliases still "
-                               "being considered.\n");
-                       break;
-
-               case WFC_VMIDI_OFF:
-                       if (virtual_midi_disable () < 0) {
-                               return -(EIO);
-                       }
-                       break;
-
-               case WFC_VMIDI_ON:
-                       if (virtual_midi_enable () < 0) {
-                               return -(EIO);
-                       }
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-\f
-/***********************************************************************/
-/* WaveFront: Linux file system interface (for access via raw synth)    */
-/***********************************************************************/
-
-static int 
-wavefront_open (struct inode *inode, struct file *file)
-{
-       /* XXX fix me */
-       dev.opened = file->f_flags;
-       return 0;
-}
-
-static int
-wavefront_release(struct inode *inode, struct file *file)
-{
-       lock_kernel();
-       dev.opened = 0;
-       dev.debug = 0;
-       unlock_kernel();
-       return 0;
-}
-
-static int
-wavefront_ioctl(struct inode *inode, struct file *file,
-               unsigned int cmd, unsigned long arg)
-{
-       wavefront_control wc;
-       int err;
-
-       switch (cmd) {
-
-       case WFCTL_WFCMD:
-               if (copy_from_user(&wc, (void __user *) arg, sizeof (wc)))
-                       return -EFAULT;
-               
-               if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-                       if (copy_to_user ((void __user *) arg, &wc, sizeof (wc)))
-                               return -EFAULT;
-               }
-
-               return err;
-               
-       case WFCTL_LOAD_SPP:
-               return wavefront_load_patch ((const char __user *) arg);
-               
-       default:
-               printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd);
-               return -(EINVAL);
-
-       }
-       return 0;
-}
-
-static /*const*/ struct file_operations wavefront_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = wavefront_ioctl,
-       .open           = wavefront_open,
-       .release        = wavefront_release,
-};
-
-\f
-/***********************************************************************/
-/* WaveFront: OSS installation and support interface                   */
-/***********************************************************************/
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-
-static struct synth_info wavefront_info =
-{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
- 0, 32, 0, 0, SYNTH_CAP_INPUT};
-
-static int
-wavefront_oss_open (int devno, int mode)
-
-{
-       dev.opened = mode;
-       return 0;
-}
-
-static void
-wavefront_oss_close (int devno)
-
-{
-       dev.opened = 0;
-       dev.debug = 0;
-       return;
-}
-
-static int
-wavefront_oss_ioctl (int devno, unsigned int cmd, void __user * arg)
-
-{
-       wavefront_control wc;
-       int err;
-
-       switch (cmd) {
-       case SNDCTL_SYNTH_INFO:
-               if(copy_to_user(arg, &wavefront_info, sizeof (wavefront_info)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_SEQ_RESETSAMPLES:
-//             printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
-               return 0; /* don't force an error */
-
-       case SNDCTL_SEQ_PERCMODE:
-               return 0; /* don't force an error */
-
-       case SNDCTL_SYNTH_MEMAVL:
-               if ((dev.freemem = wavefront_freemem ()) < 0) {
-                       printk (KERN_ERR LOGNAME "cannot get memory size\n");
-                       return -EIO;
-               } else {
-                       return dev.freemem;
-               }
-               break;
-
-       case SNDCTL_SYNTH_CONTROL:
-               if(copy_from_user (&wc, arg, sizeof (wc)))
-                       err = -EFAULT;
-               else if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-                       if(copy_to_user (arg, &wc, sizeof (wc)))
-                               err = -EFAULT;
-               }
-
-               return err;
-
-       default:
-               return -(EINVAL);
-       }
-}
-
-static int
-wavefront_oss_load_patch (int devno, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag)
-{
-
-       if (format == SYSEX_PATCH) {    /* Handled by midi_synth.c */
-               if (midi_load_patch == NULL) {
-                       printk (KERN_ERR LOGNAME
-                               "SYSEX not loadable: "
-                               "no midi patch loader!\n");
-                       return -(EINVAL);
-               }
-
-               return midi_load_patch (devno, format, addr,
-                                       offs, count, pmgr_flag);
-
-       } else if (format == GUS_PATCH) {
-               return wavefront_load_gus_patch (devno, format,
-                                                addr, offs, count, pmgr_flag);
-
-       } else if (format != WAVEFRONT_PATCH) {
-               printk (KERN_ERR LOGNAME "unknown patch format %d\n", format);
-               return -(EINVAL);
-       }
-
-       if (count < sizeof (wavefront_patch_info)) {
-               printk (KERN_ERR LOGNAME "sample header too short\n");
-               return -(EINVAL);
-       }
-
-       /* "addr" points to a user-space wavefront_patch_info */
-
-       return wavefront_load_patch (addr);
-}      
-
-static struct synth_operations wavefront_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "WaveFront",
-       .info           = &wavefront_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_WAVEFRONT,
-       .open           = wavefront_oss_open,
-       .close          = wavefront_oss_close,
-       .ioctl          = wavefront_oss_ioctl,
-       .kill_note      = midi_synth_kill_note,
-       .start_note     = midi_synth_start_note,
-       .set_instr      = midi_synth_set_instr,
-       .reset          = midi_synth_reset,
-       .load_patch     = midi_synth_load_patch,
-       .aftertouch     = midi_synth_aftertouch,
-       .controller     = midi_synth_controller,
-       .panning        = midi_synth_panning,
-       .bender         = midi_synth_bender,
-       .setup_voice    = midi_synth_setup_voice
-};
-#endif /* OSS_SUPPORT_SEQ */
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
-
-static void __init attach_wavefront (struct address_info *hw_config)
-{
-    (void) install_wavefront ();
-}
-
-static int __init probe_wavefront (struct address_info *hw_config)
-{
-    return !detect_wavefront (hw_config->irq, hw_config->io_base);
-}
-
-static void __exit unload_wavefront (struct address_info *hw_config) 
-{
-    (void) uninstall_wavefront ();
-}
-
-#endif /* OSS_SUPPORT_STATIC_INSTALL */
-
-/***********************************************************************/
-/* WaveFront: Linux modular sound kernel installation interface        */
-/***********************************************************************/
-
-static irqreturn_t
-wavefrontintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       struct wf_config *hw = dev_id;
-
-       /*
-          Some comments on interrupts. I attempted a version of this
-          driver that used interrupts throughout the code instead of
-          doing busy and/or sleep-waiting. Alas, it appears that once
-          the Motorola firmware is downloaded, the card *never*
-          generates an RX interrupt. These are successfully generated
-          during firmware loading, and after that wavefront_status()
-          reports that an interrupt is pending on the card from time
-          to time, but it never seems to be delivered to this
-          driver. Note also that wavefront_status() continues to
-          report that RX interrupts are enabled, suggesting that I
-          didn't goof up and disable them by mistake.
-
-          Thus, I stepped back to a prior version of
-          wavefront_wait(), the only place where this really
-          matters. Its sad, but I've looked through the code to check
-          on things, and I really feel certain that the Motorola
-          firmware prevents RX-ready interrupts.
-       */
-
-       if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
-               return IRQ_NONE;
-       }
-
-       hw->irq_ok = 1;
-       hw->irq_cnt++;
-       wake_up_interruptible (&hw->interrupt_sleeper);
-       return IRQ_HANDLED;
-}
-
-/* STATUS REGISTER 
-
-0 Host Rx Interrupt Enable (1=Enabled)
-1 Host Rx Register Full (1=Full)
-2 Host Rx Interrupt Pending (1=Interrupt)
-3 Unused
-4 Host Tx Interrupt (1=Enabled)
-5 Host Tx Register empty (1=Empty)
-6 Host Tx Interrupt Pending (1=Interrupt)
-7 Unused
-*/
-
-static int
-wavefront_interrupt_bits (int irq)
-
-{
-       int bits;
-
-       switch (irq) {
-       case 9:
-               bits = 0x00;
-               break;
-       case 5:
-               bits = 0x08;
-               break;
-       case 12:
-               bits = 0x10;
-               break;
-       case 15:
-               bits = 0x18;
-               break;
-       
-       default:
-               printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq);
-               bits = -1;
-       }
-
-       return bits;
-}
-
-static void
-wavefront_should_cause_interrupt (int val, int port, int timeout)
-
-{
-       unsigned long flags;
-
-       /* this will not help on SMP - but at least it compiles */
-       spin_lock_irqsave(&lock, flags);
-       dev.irq_ok = 0;
-       outb (val,port);
-       interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout);
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init wavefront_hw_reset (void)
-{
-       int bits;
-       int hwv[2];
-       unsigned long irq_mask;
-       short reported_irq;
-
-       /* IRQ already checked in init_module() */
-
-       bits = wavefront_interrupt_bits (dev.irq);
-
-       printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n");
-
-       irq_mask = probe_irq_on ();
-
-       outb (0x0, dev.control_port); 
-       outb (0x80 | 0x40 | bits, dev.data_port);       
-       wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-                                        dev.control_port,
-                                        (reset_time*HZ)/100);
-
-       reported_irq = probe_irq_off (irq_mask);
-
-       if (reported_irq != dev.irq) {
-               if (reported_irq == 0) {
-                       printk (KERN_ERR LOGNAME
-                               "No unassigned interrupts detected "
-                               "after h/w reset\n");
-               } else if (reported_irq < 0) {
-                       printk (KERN_ERR LOGNAME
-                               "Multiple unassigned interrupts detected "
-                               "after h/w reset\n");
-               } else {
-                       printk (KERN_ERR LOGNAME "autodetected IRQ %d not the "
-                               "value provided (%d)\n", reported_irq,
-                               dev.irq);
-               }
-               dev.irq = -1;
-               return 1;
-       } else {
-               printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n",
-                       reported_irq);
-       }
-
-       if (request_irq (dev.irq, wavefrontintr,
-                        IRQF_DISABLED|IRQF_SHARED,
-                        "wavefront synth", &dev) < 0) {
-               printk (KERN_WARNING LOGNAME "IRQ %d not available!\n",
-                       dev.irq);
-               return 1;
-       }
-
-       /* try reset of port */
-      
-       outb (0x0, dev.control_port); 
-  
-       /* At this point, the board is in reset, and the H/W initialization
-          register is accessed at the same address as the data port.
-     
-          Bit 7 - Enable IRQ Driver    
-          0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
-          1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
-     
-          Bit 6 - MIDI Interface Select
-
-          0 - Use the MIDI Input from the 26-pin WaveBlaster
-          compatible header as the serial MIDI source
-          1 - Use the MIDI Input from the 9-pin D connector as the
-          serial MIDI source.
-     
-          Bits 5:3 - IRQ Selection
-          0 0 0 - IRQ 2/9
-          0 0 1 - IRQ 5
-          0 1 0 - IRQ 12
-          0 1 1 - IRQ 15
-          1 0 0 - Reserved
-          1 0 1 - Reserved
-          1 1 0 - Reserved
-          1 1 1 - Reserved
-     
-          Bits 2:1 - Reserved
-          Bit 0 - Disable Boot ROM
-          0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
-          1 - memory accesses to 03FC30-03FFFFH are directed to external 
-          storage.
-     
-       */
-
-       /* configure hardware: IRQ, enable interrupts, 
-          plus external 9-pin MIDI interface selected
-       */
-
-       outb (0x80 | 0x40 | bits, dev.data_port);       
-  
-       /* CONTROL REGISTER
-
-          0 Host Rx Interrupt Enable (1=Enabled)      0x1
-          1 Unused                                    0x2
-          2 Unused                                    0x4
-          3 Unused                                    0x8
-          4 Host Tx Interrupt Enable                 0x10
-          5 Mute (0=Mute; 1=Play)                    0x20
-          6 Master Interrupt Enable (1=Enabled)      0x40
-          7 Master Reset (0=Reset; 1=Run)            0x80
-
-          Take us out of reset, mute output, master + TX + RX interrupts on.
-          
-          We'll get an interrupt presumably to tell us that the TX
-          register is clear.
-       */
-
-       wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-                                        dev.control_port,
-                                        (reset_time*HZ)/100);
-
-       /* Note: data port is now the data port, not the h/w initialization
-          port.
-        */
-
-       if (!dev.irq_ok) {
-               printk (KERN_WARNING LOGNAME
-                       "intr not received after h/w un-reset.\n");
-               goto gone_bad;
-       } 
-
-       dev.interrupts_on = 1;
-       
-       /* Note: data port is now the data port, not the h/w initialization
-          port.
-
-          At this point, only "HW VERSION" or "DOWNLOAD OS" commands
-          will work. So, issue one of them, and wait for TX
-          interrupt. This can take a *long* time after a cold boot,
-          while the ISC ROM does its RAM test. The SDK says up to 4
-          seconds - with 12MB of RAM on a Tropez+, it takes a lot
-          longer than that (~16secs). Note that the card understands
-          the difference between a warm and a cold boot, so
-          subsequent ISC2115 reboots (say, caused by module
-          reloading) will get through this much faster.
-
-          XXX Interesting question: why is no RX interrupt received first ?
-       */
-
-       wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION, 
-                                        dev.data_port, ramcheck_time*HZ);
-
-       if (!dev.irq_ok) {
-               printk (KERN_WARNING LOGNAME
-                       "post-RAM-check interrupt not received.\n");
-               goto gone_bad;
-       } 
-
-       if (!wavefront_wait (STAT_CAN_READ)) {
-               printk (KERN_WARNING LOGNAME
-                       "no response to HW version cmd.\n");
-               goto gone_bad;
-       }
-       
-       if ((hwv[0] = wavefront_read ()) == -1) {
-               printk (KERN_WARNING LOGNAME
-                       "board not responding correctly.\n");
-               goto gone_bad;
-       }
-
-       if (hwv[0] == 0xFF) { /* NAK */
-
-               /* Board's RAM test failed. Try to read error code,
-                  and tell us about it either way.
-               */
-               
-               if ((hwv[0] = wavefront_read ()) == -1) {
-                       printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-                               "(bad error code).\n");
-               } else {
-                       printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-                               "(error code: 0x%x).\n",
-                               hwv[0]);
-               }
-               goto gone_bad;
-       }
-
-       /* We're OK, just get the next byte of the HW version response */
-
-       if ((hwv[1] = wavefront_read ()) == -1) {
-               printk (KERN_WARNING LOGNAME "incorrect h/w response.\n");
-               goto gone_bad;
-       }
-
-       printk (KERN_INFO LOGNAME "hardware version %d.%d\n",
-               hwv[0], hwv[1]);
-
-       return 0;
-
-
-     gone_bad:
-       if (dev.irq >= 0) {
-               free_irq (dev.irq, &dev);
-               dev.irq = -1;
-       }
-       return (1);
-}
-
-static int __init detect_wavefront (int irq, int io_base)
-{
-       unsigned char   rbuf[4], wbuf[4];
-
-       /* TB docs say the device takes up 8 ports, but we know that
-          if there is an FX device present (i.e. a Tropez+) it really
-          consumes 16.
-       */
-
-       if (!request_region (io_base, 16, "wavfront")) {
-               printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
-                       "already in use - ignored\n", dev.base,
-                       dev.base+15);
-               return -1;
-       }
-  
-       dev.irq = irq;
-       dev.base = io_base;
-       dev.israw = 0;
-       dev.debug = debug_default;
-       dev.interrupts_on = 0;
-       dev.irq_cnt = 0;
-       dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
-
-       if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
-
-               dev.fw_version[0] = rbuf[0];
-               dev.fw_version[1] = rbuf[1];
-               printk (KERN_INFO LOGNAME
-                       "firmware %d.%d already loaded.\n",
-                       rbuf[0], rbuf[1]);
-
-               /* check that a command actually works */
-      
-               if (wavefront_cmd (WFC_HARDWARE_VERSION,
-                                  rbuf, wbuf) == 0) {
-                       dev.hw_version[0] = rbuf[0];
-                       dev.hw_version[1] = rbuf[1];
-               } else {
-                       printk (KERN_WARNING LOGNAME "not raw, but no "
-                               "hardware version!\n");
-                       release_region (io_base, 16);
-                       return 0;
-               }
-
-               if (!wf_raw) {
-                       /* will re-acquire region in install_wavefront() */
-                       release_region (io_base, 16);
-                       return 1;
-               } else {
-                       printk (KERN_INFO LOGNAME
-                               "reloading firmware anyway.\n");
-                       dev.israw = 1;
-               }
-
-       } else {
-
-               dev.israw = 1;
-               printk (KERN_INFO LOGNAME
-                       "no response to firmware probe, assume raw.\n");
-
-       }
-
-       init_waitqueue_head (&dev.interrupt_sleeper);
-
-       if (wavefront_hw_reset ()) {
-               printk (KERN_WARNING LOGNAME "hardware reset failed\n");
-               release_region (io_base, 16);
-               return 0;
-       }
-
-       /* Check for FX device, present only on Tropez+ */
-
-       dev.has_fx = (detect_wffx () == 0);
-
-       /* will re-acquire region in install_wavefront() */
-       release_region (io_base, 16);
-       return 1;
-}
-
-#include "os.h"
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-
-static int
-wavefront_download_firmware (char *path)
-
-{
-       unsigned char section[WF_SECTION_MAX];
-       char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
-       int section_cnt_downloaded = 0;
-       int fd;
-       int c;
-       int i;
-       mm_segment_t fs;
-
-       /* This tries to be a bit cleverer than the stuff Alan Cox did for
-          the generic sound firmware, in that it actually knows
-          something about the structure of the Motorola firmware. In
-          particular, it uses a version that has been stripped of the
-          20K of useless header information, and had section lengths
-          added, making it possible to load the entire OS without any
-          [kv]malloc() activity, since the longest entity we ever read is
-          42 bytes (well, WF_SECTION_MAX) long.
-       */
-
-       fs = get_fs();
-       set_fs (get_ds());
-
-       if ((fd = sys_open (path, 0, 0)) < 0) {
-               printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n",
-                       path);
-               return 1;
-       }
-
-       while (1) {
-               int x;
-
-               if ((x = sys_read (fd, &section_length, sizeof (section_length))) !=
-                   sizeof (section_length)) {
-                       printk (KERN_ERR LOGNAME "firmware read error.\n");
-                       goto failure;
-               }
-
-               if (section_length == 0) {
-                       break;
-               }
-
-               if (sys_read (fd, section, section_length) != section_length) {
-                       printk (KERN_ERR LOGNAME "firmware section "
-                               "read error.\n");
-                       goto failure;
-               }
-
-               /* Send command */
-       
-               if (wavefront_write (WFC_DOWNLOAD_OS)) {
-                       goto failure;
-               }
-       
-               for (i = 0; i < section_length; i++) {
-                       if (wavefront_write (section[i])) {
-                               goto failure;
-                       }
-               }
-       
-               /* get ACK */
-       
-               if (wavefront_wait (STAT_CAN_READ)) {
-
-                       if ((c = inb (dev.data_port)) != WF_ACK) {
-
-                               printk (KERN_ERR LOGNAME "download "
-                                       "of section #%d not "
-                                       "acknowledged, ack = 0x%x\n",
-                                       section_cnt_downloaded + 1, c);
-                               goto failure;
-               
-                       }
-
-               } else {
-                       printk (KERN_ERR LOGNAME "time out for firmware ACK.\n");
-                       goto failure;
-               }
-
-       }
-
-       sys_close (fd);
-       set_fs (fs);
-       return 0;
-
- failure:
-       sys_close (fd);
-       set_fs (fs);
-       printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n");
-       return 1;
-}
-
-static int __init wavefront_config_midi (void)
-{
-       unsigned char rbuf[4], wbuf[4];
-    
-       if (detect_wf_mpu (dev.irq, dev.base) < 0) {
-               printk (KERN_WARNING LOGNAME
-                       "could not find working MIDI device\n");
-               return -1;
-       } 
-
-       if ((dev.mididev = install_wf_mpu ()) < 0) {
-               printk (KERN_WARNING LOGNAME
-                       "MIDI interfaces not configured\n");
-               return -1;
-       }
-
-       /* Route external MIDI to WaveFront synth (by default) */
-    
-       if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) {
-               printk (KERN_WARNING LOGNAME
-                       "cannot enable MIDI-IN to synth routing.\n");
-               /* XXX error ? */
-       }
-
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       /* Get the regular MIDI patch loading function, so we can
-          use it if we ever get handed a SYSEX patch. This is
-          unlikely, because its so damn slow, but we may as well
-          leave this functionality from maui.c behind, since it
-          could be useful for sequencer applications that can
-          only use MIDI to do patch loading.
-       */
-
-       if (midi_devs[dev.mididev]->converter != NULL) {
-               midi_load_patch = midi_devs[dev.mididev]->converter->load_patch;
-               midi_devs[dev.mididev]->converter->load_patch =
-                   &wavefront_oss_load_patch;
-       }
-
-#endif /* OSS_SUPPORT_SEQ */
-       
-       /* Turn on Virtual MIDI, but first *always* turn it off,
-          since otherwise consectutive reloads of the driver will
-          never cause the hardware to generate the initial "internal" or 
-          "external" source bytes in the MIDI data stream. This
-          is pretty important, since the internal hardware generally will
-          be used to generate none or very little MIDI output, and
-          thus the only source of MIDI data is actually external. Without
-          the switch bytes, the driver will think it all comes from
-          the internal interface. Duh.
-       */
-
-       if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) { 
-               printk (KERN_WARNING LOGNAME
-                       "virtual MIDI mode not disabled\n");
-               return 0; /* We're OK, but missing the external MIDI dev */
-       }
-
-       if ((dev.ext_mididev = virtual_midi_enable ()) < 0) {
-               printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n");
-       } else {
-               if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) {
-                       printk (KERN_WARNING LOGNAME
-                               "cannot enable virtual MIDI mode.\n");
-                       virtual_midi_disable ();
-               } 
-       }
-    
-       return 0;
-}
-
-static int __init wavefront_do_reset (int atboot)
-{
-       char voices[1];
-
-       if (!atboot && wavefront_hw_reset ()) {
-               printk (KERN_WARNING LOGNAME "hw reset failed.\n");
-               goto gone_bad;
-       }
-
-       if (dev.israw) {
-               if (wavefront_download_firmware (ospath)) {
-                       goto gone_bad;
-               }
-
-               dev.israw = 0;
-
-               /* Wait for the OS to get running. The protocol for
-                  this is non-obvious, and was determined by
-                  using port-IO tracing in DOSemu and some
-                  experimentation here.
-                  
-                  Rather than using timed waits, use interrupts creatively.
-               */
-
-               wavefront_should_cause_interrupt (WFC_NOOP,
-                                                 dev.data_port,
-                                                 (osrun_time*HZ));
-
-               if (!dev.irq_ok) {
-                       printk (KERN_WARNING LOGNAME
-                               "no post-OS interrupt.\n");
-                       goto gone_bad;
-               }
-               
-               /* Now, do it again ! */
-               
-               wavefront_should_cause_interrupt (WFC_NOOP,
-                                                 dev.data_port, (10*HZ));
-               
-               if (!dev.irq_ok) {
-                       printk (KERN_WARNING LOGNAME
-                               "no post-OS interrupt(2).\n");
-                       goto gone_bad;
-               }
-
-               /* OK, no (RX/TX) interrupts any more, but leave mute
-                  in effect. 
-               */
-               
-               outb (0x80|0x40, dev.control_port); 
-
-               /* No need for the IRQ anymore */
-               
-               free_irq (dev.irq, &dev);
-
-       }
-
-       if (dev.has_fx && fx_raw) {
-               wffx_init ();
-       }
-
-       /* SETUPSND.EXE asks for sample memory config here, but since i
-          have no idea how to interpret the result, we'll forget
-          about it.
-       */
-       
-       if ((dev.freemem = wavefront_freemem ()) < 0) {
-               goto gone_bad;
-       }
-               
-       printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024);
-
-       if (wavefront_write (0xf0) ||
-           wavefront_write (1) ||
-           (wavefront_read () < 0)) {
-               dev.debug = 0;
-               printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n");
-               goto gone_bad;
-       }
-
-       voices[0] = 32;
-
-       if (wavefront_cmd (WFC_SET_NVOICES, NULL, voices)) {
-               printk (KERN_WARNING LOGNAME
-                       "cannot set number of voices to 32.\n");
-               goto gone_bad;
-       }
-
-
-       return 0;
-
- gone_bad:
-       /* reset that sucker so that it doesn't bother us. */
-
-       outb (0x0, dev.control_port);
-       dev.interrupts_on = 0;
-       if (dev.irq >= 0) {
-               free_irq (dev.irq, &dev);
-       }
-       return 1;
-}
-
-static int __init wavefront_init (int atboot)
-{
-       int samples_are_from_rom;
-
-       if (dev.israw) {
-               samples_are_from_rom = 1;
-       } else {
-               /* XXX is this always true ? */
-               samples_are_from_rom = 0;
-       }
-
-       if (dev.israw || fx_raw) {
-               if (wavefront_do_reset (atboot)) {
-                       return -1;
-               }
-       }
-
-       wavefront_get_sample_status (samples_are_from_rom);
-       wavefront_get_program_status ();
-       wavefront_get_patch_status ();
-
-       /* Start normal operation: unreset, master interrupt enabled, no mute
-       */
-
-       outb (0x80|0x40|0x20, dev.control_port); 
-
-       return (0);
-}
-
-static int __init install_wavefront (void)
-{
-       if (!request_region (dev.base+2, 6, "wavefront synth"))
-               return -1;
-
-       if (dev.has_fx) {
-               if (!request_region (dev.base+8, 8, "wavefront fx")) {
-                       release_region (dev.base+2, 6);
-                       return -1;
-               }
-       }
-
-       if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
-               printk (KERN_ERR LOGNAME "cannot register raw synth\n");
-               goto err_out;
-       }
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
-               printk (KERN_ERR LOGNAME "Too many sequencers\n");
-               /* FIXME: leak: should unregister sound synth */
-               goto err_out;
-       } else {
-               synth_devs[dev.oss_dev] = &wavefront_operations;
-       }
-#endif /* OSS_SUPPORT_SEQ */
-
-       if (wavefront_init (1) < 0) {
-               printk (KERN_WARNING LOGNAME "initialization failed.\n");
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-               sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-
-               goto err_out;
-       }
-    
-       if (wavefront_config_midi ()) {
-               printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
-       }
-
-       return dev.oss_dev;
-
-err_out:
-       release_region (dev.base+2, 6);
-       if (dev.has_fx)
-               release_region (dev.base+8, 8);
-       return -1;
-}
-
-static void __exit uninstall_wavefront (void)
-{
-       /* the first two i/o addresses are freed by the wf_mpu code */
-       release_region (dev.base+2, 6);
-
-       if (dev.has_fx) {
-               release_region (dev.base+8, 8);
-       }
-
-       unregister_sound_synth (dev.synth_dev);
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-       uninstall_wf_mpu ();
-}
-
-/***********************************************************************/
-/*   WaveFront FX control                                              */
-/***********************************************************************/
-
-#include "yss225.h"
-
-/* Control bits for the Load Control Register
- */
-
-#define FX_LSB_TRANSFER 0x01    /* transfer after DSP LSB byte written */
-#define FX_MSB_TRANSFER 0x02    /* transfer after DSP MSB byte written */
-#define FX_AUTO_INCR    0x04    /* auto-increment DSP address after transfer */
-
-static int
-wffx_idle (void) 
-    
-{
-       int i;
-       unsigned int x = 0x80;
-    
-       for (i = 0; i < 1000; i++) {
-               x = inb (dev.fx_status);
-               if ((x & 0x80) == 0) {
-                       break;
-               }
-       }
-    
-       if (x & 0x80) {
-               printk (KERN_ERR LOGNAME "FX device never idle.\n");
-               return 0;
-       }
-    
-       return (1);
-}
-
-int __init detect_wffx (void)
-{
-       /* This is a crude check, but its the best one I have for now.
-          Certainly on the Maui and the Tropez, wffx_idle() will
-          report "never idle", which suggests that this test should
-          work OK.
-       */
-
-       if (inb (dev.fx_status) & 0x80) {
-               printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n");
-               return -1;
-       }
-
-       return 0;
-}      
-
-static void
-wffx_mute (int onoff)
-    
-{
-       if (!wffx_idle()) {
-               return;
-       }
-    
-       outb (onoff ? 0x02 : 0x00, dev.fx_op);
-}
-
-static int
-wffx_memset (int page,
-            int addr, int cnt, unsigned short *data)
-{
-       if (page < 0 || page > 7) {
-               printk (KERN_ERR LOGNAME "FX memset: "
-                       "page must be >= 0 and <= 7\n");
-               return -(EINVAL);
-       }
-
-       if (addr < 0 || addr > 0x7f) {
-               printk (KERN_ERR LOGNAME "FX memset: "
-                       "addr must be >= 0 and <= 7f\n");
-               return -(EINVAL);
-       }
-
-       if (cnt == 1) {
-
-               outb (FX_LSB_TRANSFER, dev.fx_lcr);
-               outb (page, dev.fx_dsp_page);
-               outb (addr, dev.fx_dsp_addr);
-               outb ((data[0] >> 8), dev.fx_dsp_msb);
-               outb ((data[0] & 0xff), dev.fx_dsp_lsb);
-
-               printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n",
-                       page, addr, data[0]);
-       
-       } else {
-               int i;
-
-               outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-               outb (page, dev.fx_dsp_page);
-               outb (addr, dev.fx_dsp_addr);
-
-               for (i = 0; i < cnt; i++) {
-                       outb ((data[i] >> 8), dev.fx_dsp_msb);
-                       outb ((data[i] & 0xff), dev.fx_dsp_lsb);
-                       if (!wffx_idle ()) {
-                               break;
-                       }
-               }
-
-               if (i != cnt) {
-                       printk (KERN_WARNING LOGNAME
-                               "FX memset "
-                               "(0x%x, 0x%x, %p, %d) incomplete\n",
-                               page, addr, data, cnt);
-                       return -(EIO);
-               }
-       }
-
-       return 0;
-}
-
-static int
-wffx_ioctl (wavefront_fx_info *r)
-
-{
-       unsigned short page_data[256];
-       unsigned short *pd;
-
-       switch (r->request) {
-       case WFFX_MUTE:
-               wffx_mute (r->data[0]);
-               return 0;
-
-       case WFFX_MEMSET:
-
-               if (r->data[2] <= 0) {
-                       printk (KERN_ERR LOGNAME "cannot write "
-                               "<= 0 bytes to FX\n");
-                       return -(EINVAL);
-               } else if (r->data[2] == 1) {
-                       pd = (unsigned short *) &r->data[3];
-               } else {
-                       if (r->data[2] > sizeof (page_data)) {
-                               printk (KERN_ERR LOGNAME "cannot write "
-                                       "> 255 bytes to FX\n");
-                               return -(EINVAL);
-                       }
-                       if (copy_from_user(page_data,
-                                          (unsigned char __user *)r->data[3],
-                                          r->data[2]))
-                               return -EFAULT;
-                       pd = page_data;
-               }
-
-               return wffx_memset (r->data[0], /* page */
-                                   r->data[1], /* addr */
-                                   r->data[2], /* cnt */
-                                   pd);
-
-       default:
-               printk (KERN_WARNING LOGNAME
-                       "FX: ioctl %d not yet supported\n",
-                       r->request);
-               return -(EINVAL);
-       }
-}
-
-/* YSS225 initialization.
-
-   This code was developed using DOSEMU. The Turtle Beach SETUPSND
-   utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
-   of the port I/O done, using the Yamaha faxback document as a guide
-   to add more logic to the code. Its really pretty weird.
-
-   There was an alternative approach of just dumping the whole I/O
-   sequence as a series of port/value pairs and a simple loop
-   that output it. However, I hope that eventually I'll get more
-   control over what this code does, and so I tried to stick with
-   a somewhat "algorithmic" approach.
-*/
-
-static int __init wffx_init (void)
-{
-       int i;
-       int j;
-
-       /* Set all bits for all channels on the MOD unit to zero */
-       /* XXX But why do this twice ? */
-
-       for (j = 0; j < 2; j++) {
-               for (i = 0x10; i <= 0xff; i++) {
-           
-                       if (!wffx_idle ()) {
-                               return (-1);
-                       }
-           
-                       outb (i, dev.fx_mod_addr);
-                       outb (0x0, dev.fx_mod_data);
-               }
-       }
-
-       if (!wffx_idle()) return (-1);
-       outb (0x02, dev.fx_op);                        /* mute on */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x44, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x42, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x43, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x7c, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x7e, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x46, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x49, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x47, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x4a, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-
-       /* either because of stupidity by TB's programmers, or because it
-          actually does something, rezero the MOD page.
-       */
-       for (i = 0x10; i <= 0xff; i++) {
-       
-               if (!wffx_idle ()) {
-                       return (-1);
-               }
-       
-               outb (i, dev.fx_mod_addr);
-               outb (0x0, dev.fx_mod_data);
-       }
-       /* load page zero */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x00, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_zero); i += 2) {
-               outb (page_zero[i], dev.fx_dsp_msb);
-               outb (page_zero[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Now load page one */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x01, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_one); i += 2) {
-               outb (page_one[i], dev.fx_dsp_msb);
-               outb (page_one[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x02, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_two); i++) {
-               outb (page_two[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x03, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_three); i++) {
-               outb (page_three[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x04, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_four); i++) {
-               outb (page_four[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Load memory area (page six) */
-    
-       outb (FX_LSB_TRANSFER, dev.fx_lcr); 
-       outb (0x06, dev.fx_dsp_page); 
-
-       for (i = 0; i < sizeof (page_six); i += 3) {
-               outb (page_six[i], dev.fx_dsp_addr);
-               outb (page_six[i+1], dev.fx_dsp_msb);
-               outb (page_six[i+2], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_seven); i += 2) {
-               outb (page_seven[i], dev.fx_dsp_msb);
-               outb (page_seven[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Now setup the MOD area. We do this algorithmically in order to
-          save a little data space. It could be done in the same fashion
-          as the "pages".
-       */
-
-       for (i = 0x00; i <= 0x0f; i++) {
-               outb (0x01, dev.fx_mod_addr);
-               outb (i, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-               outb (0x02, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xb0; i <= 0xbf; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x20, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xf0; i <= 0xff; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x20, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x10; i <= 0x1d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xff, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x1e, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x1f; i <= 0x2d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xff, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x2e, dev.fx_mod_addr);
-       outb (0x00, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x2f; i <= 0x3e; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x3f, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x40; i <= 0x4d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x4e, dev.fx_mod_addr);
-       outb (0x0e, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0x4f, dev.fx_mod_addr);
-       outb (0x0e, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-
-       for (i = 0x50; i <= 0x6b; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x6c, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6d, dev.fx_mod_addr);
-       outb (0x00, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6e, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6f, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x70; i <= 0x7f; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xc0, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       for (i = 0x80; i <= 0xaf; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xc0; i <= 0xdd; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0xde, dev.fx_mod_addr);
-       outb (0x10, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xdf, dev.fx_mod_addr);
-       outb (0x10, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0xe0; i <= 0xef; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x00; i <= 0x0f; i++) {
-               outb (0x01, dev.fx_mod_addr);
-               outb (i, dev.fx_mod_data);
-               outb (0x02, dev.fx_mod_addr);
-               outb (0x01, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x02, dev.fx_op); /* mute on */
-
-       /* Now set the coefficients and so forth for the programs above */
-
-       for (i = 0; i < sizeof (coefficients); i += 4) {
-               outb (coefficients[i], dev.fx_dsp_page);
-               outb (coefficients[i+1], dev.fx_dsp_addr);
-               outb (coefficients[i+2], dev.fx_dsp_msb);
-               outb (coefficients[i+3], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Some settings (?) that are too small to bundle into loops */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x1e, dev.fx_mod_addr);
-       outb (0x14, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xde, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xdf, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-    
-       /* some more coefficients */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x06, dev.fx_dsp_page);
-       outb (0x78, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x40, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x03, dev.fx_dsp_addr);
-       outb (0x0f, dev.fx_dsp_msb);
-       outb (0xff, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x0b, dev.fx_dsp_addr);
-       outb (0x0f, dev.fx_dsp_msb);
-       outb (0xff, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x02, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x0a, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x46, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x49, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-    
-       /* Now, for some strange reason, lets reload every page
-          and all the coefficients over again. I have *NO* idea
-          why this is done. I do know that no sound is produced
-          is this phase is omitted.
-       */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x00, dev.fx_dsp_page);  
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_zero_v2); i += 2) {
-               outb (page_zero_v2[i], dev.fx_dsp_msb);
-               outb (page_zero_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x01, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_one_v2); i += 2) {
-               outb (page_one_v2[i], dev.fx_dsp_msb);
-               outb (page_one_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       if (!wffx_idle()) return (-1);
-       if (!wffx_idle()) return (-1);
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x02, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_two_v2); i++) {
-               outb (page_two_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x03, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_three_v2); i++) {
-               outb (page_three_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x04, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_four_v2); i++) {
-               outb (page_four_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x06, dev.fx_dsp_page);
-
-       /* Page six v.2 is algorithmic */
-    
-       for (i = 0x10; i <= 0x3e; i += 2) {
-               outb (i, dev.fx_dsp_addr);
-               outb (0x00, dev.fx_dsp_msb);
-               outb (0x00, dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_seven_v2); i += 2) {
-               outb (page_seven_v2[i], dev.fx_dsp_msb);
-               outb (page_seven_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x00; i < sizeof(mod_v2); i += 2) {
-               outb (mod_v2[i], dev.fx_mod_addr);
-               outb (mod_v2[i+1], dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0; i < sizeof (coefficients2); i += 4) {
-               outb (coefficients2[i], dev.fx_dsp_page);
-               outb (coefficients2[i+1], dev.fx_dsp_addr);
-               outb (coefficients2[i+2], dev.fx_dsp_msb);
-               outb (coefficients2[i+3], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0; i < sizeof (coefficients3); i += 2) {
-               int x;
-
-               outb (0x07, dev.fx_dsp_page);
-               x = (i % 4) ? 0x4e : 0x4c;
-               outb (x, dev.fx_dsp_addr);
-               outb (coefficients3[i], dev.fx_dsp_msb);
-               outb (coefficients3[i+1], dev.fx_dsp_lsb);
-       }
-
-       outb (0x00, dev.fx_op); /* mute off */
-       if (!wffx_idle()) return (-1);
-
-       return (0);
-}
-
-static int io = -1;
-static int irq = -1;
-
-MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
-MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
-MODULE_LICENSE("GPL");
-module_param       (io, int, 0);
-module_param       (irq, int, 0);
-
-static int __init init_wavfront (void)
-{
-       printk ("Turtle Beach WaveFront Driver\n"
-               "Copyright (C) by Hannu Solvainen, "
-               "Paul Barton-Davis 1993-1998.\n");
-
-       /* XXX t'would be lovely to ask the CS4232 for these values, eh ? */
-
-       if (io == -1 || irq == -1) {
-               printk (KERN_INFO LOGNAME "irq and io options must be set.\n");
-               return -EINVAL;
-       }
-
-       if (wavefront_interrupt_bits (irq) < 0) {
-               printk (KERN_INFO LOGNAME
-                       "IRQ must be 9, 5, 12 or 15 (not %d)\n", irq);
-               return -ENODEV;
-       }
-
-       if (detect_wavefront (irq, io) < 0) {
-               return -ENODEV;
-       } 
-
-       if (install_wavefront () < 0) {
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static void __exit cleanup_wavfront (void)
-{
-       uninstall_wavefront ();
-}
-
-module_init(init_wavfront);
-module_exit(cleanup_wavfront);
diff --git a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c
deleted file mode 100644 (file)
index 3f3a390..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * sound/wf_midi.c
- *
- * The low level driver for the WaveFront ICS2115 MIDI interface(s)
- * Note that there is also an MPU-401 emulation (actually, a UART-401
- * emulation) on the CS4232 on the Tropez Plus. This code has nothing
- * to do with that interface at all.
- *
- * The interface is essentially just a UART-401, but is has the
- * interesting property of supporting what Turtle Beach called
- * "Virtual MIDI" mode. In this mode, there are effectively *two*
- * MIDI buses accessible via the interface, one that is routed
- * solely to/from the external WaveFront synthesizer and the other
- * corresponding to the pin/socket connector used to link external
- * MIDI devices to the board.
- *
- * This driver fully supports this mode, allowing two distinct
- * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
- * completely independently, giving 32 channels of MIDI routing,
- * 16 to the WaveFront synth and 16 to the external MIDI bus.
- *
- * Switching between the two is accomplished externally by the driver
- * using the two otherwise unused MIDI bytes. See the code for more details.
- *
- * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
- *
- * The main reason to turn off Virtual MIDI mode is when you want to
- * tightly couple the WaveFront synth with an external MIDI
- * device. You won't be able to distinguish the source of any MIDI
- * data except via SysEx ID, but thats probably OK, since for the most
- * part, the WaveFront won't be sending any MIDI data at all.
- *  
- * The main reason to turn on Virtual MIDI Mode is to provide two
- * completely independent 16-channel MIDI buses, one to the
- * WaveFront and one to any external MIDI devices. Given the 32
- * voice nature of the WaveFront, its pretty easy to find a use
- * for all 16 channels driving just that synth.
- *
- */
-
-/*
- * Copyright (C) by Paul Barton-Davis 1998
- * Some portions of this file are derived from work that is:
- *
- *    CopyriGht (C) by Hannu Savolainen 1993-1996
- *
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#ifdef MODULE
-
-struct wf_mpu_config {
-       int             base;
-#define        DATAPORT(d)   (d)->base
-#define        COMDPORT(d)   (d)->base+1
-#define        STATPORT(d)   (d)->base+1
-
-       int             irq;
-       int             opened;
-       int             devno;
-       int             synthno;
-       int             mode;
-#define MODE_MIDI      1
-#define MODE_SYNTH     2
-
-       void            (*inputintr) (int dev, unsigned char data);
-       char isvirtual;                /* do virtual I/O stuff */
-};
-
-static struct wf_mpu_config  devs[2];
-static struct wf_mpu_config *phys_dev = &devs[0];
-static struct wf_mpu_config *virt_dev = &devs[1];
-
-static void start_uart_mode (void);
-static DEFINE_SPINLOCK(lock);
-
-#define        OUTPUT_READY    0x40
-#define        INPUT_AVAIL     0x80
-#define        MPU_ACK         0xFE
-#define        UART_MODE_ON    0x3F
-
-static inline int wf_mpu_status (void)
-{
-       return inb (STATPORT (phys_dev));
-}
-
-static inline int input_avail (void)
-{
-       return !(wf_mpu_status() & INPUT_AVAIL);
-}
-
-static inline int output_ready (void)
-{
-       return !(wf_mpu_status() & OUTPUT_READY);
-}
-
-static inline int  read_data (void)
-{
-       return inb (DATAPORT (phys_dev));
-}
-
-static inline void write_data (unsigned char byte)
-{
-       outb (byte, DATAPORT (phys_dev));
-}
-
-/*
- * States for the input scanner (should be in dev_table.h)
- */
-
-#define MST_SYSMSG             100     /* System message (sysx etc). */
-#define MST_MTC                        102     /* Midi Time Code (MTC) qframe msg */
-#define MST_SONGSEL            103     /* Song select */
-#define MST_SONGPOS            104     /* Song position pointer */
-#define MST_TIMED              105     /* Leading timing byte rcvd */
-
-/* buffer space check for input scanner */
-
-#define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
-{printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
-       mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
-
-static unsigned char len_tab[] =       /* # of data bytes following a status
-                                        */
-{
-       2,                              /* 8x */
-       2,                              /* 9x */
-       2,                              /* Ax */
-       2,                              /* Bx */
-       1,                              /* Cx */
-       1,                              /* Dx */
-       2,                              /* Ex */
-       0                               /* Fx */
-};
-
-static int
-wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
-
-{
-       struct midi_input_info *mi = &midi_devs[devno]->in_info;
-
-       switch (mi->m_state) {
-       case MST_INIT:
-               switch (midic) {
-               case 0xf8:
-                       /* Timer overflow */
-                       break;
-               
-               case 0xfc:
-                       break;
-               
-               case 0xfd:
-                       /* XXX do something useful with this. If there is
-                          an external MIDI timer (e.g. a hardware sequencer,
-                          a useful timer can be derived ...
-                  
-                          For now, no timer support.
-                       */
-                       break;
-               
-               case 0xfe:
-                       return MPU_ACK;
-                       break;
-               
-               case 0xf0:
-               case 0xf1:
-               case 0xf2:
-               case 0xf3:
-               case 0xf4:
-               case 0xf5:
-               case 0xf6:
-               case 0xf7:
-                       break;
-               
-               case 0xf9:
-                       break;
-               
-               case 0xff:
-                       mi->m_state = MST_SYSMSG;
-                       break;
-               
-               default:
-                       if (midic <= 0xef) {
-                               mi->m_state = MST_TIMED;
-                       }
-                       else
-                               printk (KERN_ERR "<MPU: Unknown event %02x> ",
-                                       midic);
-               }
-               break;
-         
-       case MST_TIMED:
-       {
-               int             msg = ((int) (midic & 0xf0) >> 4);
-         
-               mi->m_state = MST_DATA;
-         
-               if (msg < 8) {  /* Data byte */
-             
-                       msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
-                       msg -= 8;
-                       mi->m_left = len_tab[msg] - 1;
-             
-                       mi->m_ptr = 2;
-                       mi->m_buf[0] = mi->m_prev_status;
-                       mi->m_buf[1] = midic;
-
-                       if (mi->m_left <= 0) {
-                               mi->m_state = MST_INIT;
-                               do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                               mi->m_ptr = 0;
-                       }
-               } else if (msg == 0xf) {        /* MPU MARK */
-             
-                       mi->m_state = MST_INIT;
-
-                       switch (midic) {
-                       case 0xf8:
-                               break;
-                   
-                       case 0xf9:
-                               break;
-                   
-                       case 0xfc:
-                               break;
-                   
-                       default:
-                               break;
-                       }
-               } else {
-                       mi->m_prev_status = midic;
-                       msg -= 8;
-                       mi->m_left = len_tab[msg];
-             
-                       mi->m_ptr = 1;
-                       mi->m_buf[0] = midic;
-             
-                       if (mi->m_left <= 0) {
-                               mi->m_state = MST_INIT;
-                               do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                               mi->m_ptr = 0;
-                       }
-               }
-       }
-       break;
-
-       case MST_SYSMSG:
-               switch (midic) {
-               case 0xf0:
-                       mi->m_state = MST_SYSEX;
-                       break;
-           
-               case 0xf1:
-                       mi->m_state = MST_MTC;
-                       break;
-
-               case 0xf2:
-                       mi->m_state = MST_SONGPOS;
-                       mi->m_ptr = 0;
-                       break;
-           
-               case 0xf3:
-                       mi->m_state = MST_SONGSEL;
-                       break;
-           
-               case 0xf6:
-                       mi->m_state = MST_INIT;
-           
-                       /*
-                        *    Real time messages
-                        */
-               case 0xf8:
-                       /* midi clock */
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xfA:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFB:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFC:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFE:
-                       /* active sensing */
-                       mi->m_state = MST_INIT;
-                       break;
-           
-               case 0xff:
-                       mi->m_state = MST_INIT;
-                       break;
-
-               default:
-                       printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic);
-                       mi->m_state = MST_INIT;
-               }
-               break;
-
-       case MST_MTC:
-               mi->m_state = MST_INIT;
-               break;
-
-       case MST_SYSEX:
-               if (midic == 0xf7) {
-                       mi->m_state = MST_INIT;
-               } else {
-                       /* XXX fix me */
-               }
-               break;
-
-       case MST_SONGPOS:
-               BUFTEST (mi);
-               mi->m_buf[mi->m_ptr++] = midic;
-               if (mi->m_ptr == 2) {
-                       mi->m_state = MST_INIT;
-                       mi->m_ptr = 0;
-                       /* XXX need ext MIDI timer support */
-               }
-               break;
-
-       case MST_DATA:
-               BUFTEST (mi);
-               mi->m_buf[mi->m_ptr++] = midic;
-               if ((--mi->m_left) <= 0) {
-                       mi->m_state = MST_INIT;
-                       do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                       mi->m_ptr = 0;
-               }
-               break;
-
-       default:
-               printk (KERN_ERR "Bad state %d ", mi->m_state);
-               mi->m_state = MST_INIT;
-       }
-
-       return 1;
-}
-
-static irqreturn_t
-wf_mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
-
-{
-       struct wf_mpu_config *physical_dev = dev_id;
-       static struct wf_mpu_config *input_dev;
-       struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
-       int n;
-
-       if (!input_avail()) { /* not for us */
-               return IRQ_NONE;
-       }
-
-       if (mi->m_busy)
-               return IRQ_HANDLED;
-       spin_lock(&lock);
-       mi->m_busy = 1;
-
-       if (!input_dev) {
-               input_dev = physical_dev;
-       }
-
-       n = 50; /* XXX why ? */
-
-       do {
-               unsigned char c = read_data ();
-      
-               if (phys_dev->isvirtual) {
-
-                       if (c == WF_EXTERNAL_SWITCH) {
-                               input_dev = virt_dev;
-                               continue;
-                       } else if (c == WF_INTERNAL_SWITCH) { 
-                               input_dev = phys_dev;
-                               continue;
-                       } /* else just leave it as it is */
-
-               } else {
-                       input_dev = phys_dev;
-               }
-
-               if (input_dev->mode == MODE_SYNTH) {
-         
-                       wf_mpu_input_scanner (input_dev->devno,
-                                             input_dev->synthno, c);
-         
-               } else if (input_dev->opened & OPEN_READ) {
-         
-                       if (input_dev->inputintr) {
-                               input_dev->inputintr (input_dev->devno, c);
-                       } 
-               }
-
-       } while (input_avail() && n-- > 0);
-
-       mi->m_busy = 0;
-       spin_unlock(&lock);
-       return IRQ_HANDLED;
-}
-
-static int
-wf_mpu_open (int dev, int mode,
-            void            (*input) (int dev, unsigned char data),
-            void            (*output) (int dev)
-       )
-{
-       struct wf_mpu_config *devc;
-
-       if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-               return -(ENXIO);
-
-       if (phys_dev->devno == dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return -(EINVAL);
-       }
-
-       if (devc->opened) {
-               return -(EBUSY);
-       }
-
-       devc->mode = MODE_MIDI;
-       devc->opened = mode;
-       devc->synthno = 0;
-
-       devc->inputintr = input;
-       return 0;
-}
-static void
-wf_mpu_close (int dev)
-{
-       struct wf_mpu_config *devc;
-
-       if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-               return;
-
-       if (phys_dev->devno == dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return;
-       }
-
-       devc->mode = 0;
-       devc->inputintr = NULL;
-       devc->opened = 0;
-}
-
-static int
-wf_mpu_out (int dev, unsigned char midi_byte)
-{
-       int             timeout;
-       unsigned long   flags;
-       static int lastoutdev = -1;
-       unsigned char switchch;
-
-       if (phys_dev->isvirtual && lastoutdev != dev) {
-      
-               if (dev == phys_dev->devno) { 
-                       switchch = WF_INTERNAL_SWITCH;
-               } else if (dev == virt_dev->devno) { 
-                       switchch = WF_EXTERNAL_SWITCH;
-               } else {
-                       printk (KERN_ERR "WF-MPU: bad device number %d", dev);
-                       return (0);
-               }
-
-               /* XXX fix me */
-      
-               for (timeout = 30000; timeout > 0 && !output_ready ();
-                    timeout--);
-      
-               spin_lock_irqsave(&lock,flags);
-      
-               if (!output_ready ()) {
-                       printk (KERN_WARNING "WF-MPU: Send switch "
-                               "byte timeout\n");
-                       spin_unlock_irqrestore(&lock,flags);
-                       return 0;
-               }
-      
-               write_data (switchch);
-               spin_unlock_irqrestore(&lock,flags);
-       } 
-
-       lastoutdev = dev;
-
-       /*
-        * Sometimes it takes about 30000 loops before the output becomes ready
-        * (After reset). Normally it takes just about 10 loops.
-        */
-
-       /* XXX fix me */
-
-       for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
-
-       spin_lock_irqsave(&lock,flags);
-       if (!output_ready ()) {
-               spin_unlock_irqrestore(&lock,flags);
-               printk (KERN_WARNING "WF-MPU: Send data timeout\n");
-               return 0;
-       }
-
-       write_data (midi_byte);
-       spin_unlock_irqrestore(&lock,flags);
-
-       return 1;
-}
-
-static inline int wf_mpu_start_read (int dev) {
-       return 0;
-}
-
-static inline int wf_mpu_end_read (int dev) {
-       return 0;
-}
-
-static int wf_mpu_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-       printk (KERN_WARNING
-               "WF-MPU: Intelligent mode not supported by hardware.\n");
-       return -(EINVAL);
-}
-
-static int wf_mpu_buffer_status (int dev)
-{
-       return 0;
-}
-
-static struct synth_operations wf_mpu_synth_operations[2];
-static struct midi_operations  wf_mpu_midi_operations[2];
-
-static struct midi_operations wf_mpu_midi_proto =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
-       .in_info        = {0},   /* in_info */
-       .open           = wf_mpu_open,
-       .close          = wf_mpu_close,
-       .ioctl          = wf_mpu_ioctl,
-       .outputc        = wf_mpu_out,
-       .start_read     = wf_mpu_start_read,
-       .end_read       = wf_mpu_end_read,
-       .buffer_status  = wf_mpu_buffer_status,
-};
-
-static struct synth_info wf_mpu_synth_info_proto =
-{"WaveFront MPU-401 interface", 0,
- SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
-
-static struct synth_info wf_mpu_synth_info[2];
-
-static int
-wf_mpu_synth_ioctl (int dev, unsigned int cmd, void __user *arg)
-{
-       int             midi_dev;
-       int index;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
-               return -(ENXIO);
-
-       if (midi_dev == phys_dev->devno) {
-               index = 0;
-       } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
-               index = 1;
-       } else {
-               return -(EINVAL);
-       }
-
-       switch (cmd) {
-
-       case SNDCTL_SYNTH_INFO:
-               if (copy_to_user(arg,
-                             &wf_mpu_synth_info[index],
-                             sizeof (struct synth_info)))
-                       return -EFAULT;
-               return 0;
-       
-       case SNDCTL_SYNTH_MEMAVL:
-               return 0x7fffffff;
-       
-       default:
-               return -EINVAL;
-       }
-}
-
-static int
-wf_mpu_synth_open (int dev, int mode)
-{
-       int             midi_dev;
-       struct wf_mpu_config *devc;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
-               return -(ENXIO);
-       }
-  
-       if (phys_dev->devno == midi_dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return -(EINVAL);
-       }
-
-       if (devc->opened) {
-               return -(EBUSY);
-       }
-  
-       devc->mode = MODE_SYNTH;
-       devc->synthno = dev;
-       devc->opened = mode;
-       devc->inputintr = NULL;
-       return 0;
-}
-
-static void
-wf_mpu_synth_close (int dev)
-{
-       int             midi_dev;
-       struct wf_mpu_config *devc;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (phys_dev->devno == midi_dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return;
-       }
-
-       devc->inputintr = NULL;
-       devc->opened = 0;
-       devc->mode = 0;
-}
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME        "WaveFront (MIDI)"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct synth_operations wf_mpu_synth_proto =
-{
-       .owner          = THIS_MODULE,
-       .id             = "WaveFront (ICS2115)",
-       .info           = NULL,  /* info field, filled in during configuration */
-       .midi_dev       = 0,     /* MIDI dev XXX should this be -1 ? */
-       .synth_type     = SYNTH_TYPE_MIDI,
-       .synth_subtype  = SAMPLE_TYPE_WAVEFRONT,
-       .open           = wf_mpu_synth_open,
-       .close          = wf_mpu_synth_close,
-       .ioctl          = wf_mpu_synth_ioctl,
-       .kill_note      = midi_synth_kill_note,
-       .start_note     = midi_synth_start_note,
-       .set_instr      = midi_synth_set_instr,
-       .reset          = midi_synth_reset,
-       .hw_control     = midi_synth_hw_control,
-       .load_patch     = midi_synth_load_patch,
-       .aftertouch     = midi_synth_aftertouch,
-       .controller     = midi_synth_controller,
-       .panning        = midi_synth_panning,
-       .bender         = midi_synth_bender,
-       .setup_voice    = midi_synth_setup_voice,
-       .send_sysex     = midi_synth_send_sysex
-};
-
-static int
-config_wf_mpu (struct wf_mpu_config *dev)
-
-{
-       int is_external;
-       char *name;
-       int index;
-
-       if (dev == phys_dev) {
-               name = "WaveFront internal MIDI";
-               is_external = 0;
-               index = 0;
-               memcpy ((char *) &wf_mpu_synth_operations[index],
-                       (char *) &wf_mpu_synth_proto,
-                       sizeof (struct synth_operations));
-       } else {
-               name = "WaveFront external MIDI";
-               is_external = 1;
-               index = 1;
-               /* no synth operations for an external MIDI interface */
-       }
-
-       memcpy ((char *) &wf_mpu_synth_info[dev->devno],
-               (char *) &wf_mpu_synth_info_proto,
-               sizeof (struct synth_info));
-
-       strcpy (wf_mpu_synth_info[index].name, name);
-
-       wf_mpu_synth_operations[index].midi_dev = dev->devno;
-       wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
-
-       memcpy ((char *) &wf_mpu_midi_operations[index],
-               (char *) &wf_mpu_midi_proto,
-               sizeof (struct midi_operations));
-  
-       if (is_external) {
-               wf_mpu_midi_operations[index].converter = NULL;
-       } else {
-               wf_mpu_midi_operations[index].converter =
-                       &wf_mpu_synth_operations[index];
-       }
-
-       strcpy (wf_mpu_midi_operations[index].info.name, name);
-
-       midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
-       midi_devs[dev->devno]->in_info.m_busy = 0;
-       midi_devs[dev->devno]->in_info.m_state = MST_INIT;
-       midi_devs[dev->devno]->in_info.m_ptr = 0;
-       midi_devs[dev->devno]->in_info.m_left = 0;
-       midi_devs[dev->devno]->in_info.m_prev_status = 0;
-
-       devs[index].opened = 0;
-       devs[index].mode = 0;
-
-       return (0);
-}
-
-int virtual_midi_enable (void)
-
-{
-       if ((virt_dev->devno < 0) &&
-           (virt_dev->devno = sound_alloc_mididev()) == -1) {
-               printk (KERN_ERR
-                       "WF-MPU: too many midi devices detected\n");
-               return -1;
-       }
-
-       config_wf_mpu (virt_dev);
-
-       phys_dev->isvirtual = 1;
-       return virt_dev->devno;
-}
-
-int
-virtual_midi_disable (void)
-
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       wf_mpu_close (virt_dev->devno);
-       /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
-       phys_dev->isvirtual = 0;
-
-       spin_unlock_irqrestore(&lock,flags);
-
-       return 0;
-}
-
-int __init detect_wf_mpu (int irq, int io_base)
-{
-       if (!request_region(io_base, 2, "wavefront midi")) {
-               printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
-                       io_base);
-               return -1;
-       }
-
-       phys_dev->base = io_base;
-       phys_dev->irq = irq;
-       phys_dev->devno = -1;
-       virt_dev->devno = -1;
-
-       return 0;
-}
-
-int __init install_wf_mpu (void)
-{
-       if ((phys_dev->devno = sound_alloc_mididev()) < 0){
-
-               printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
-               release_region(phys_dev->base, 2);
-               return -1;
-       }
-
-       phys_dev->isvirtual = 0;
-
-       if (config_wf_mpu (phys_dev)) {
-
-               printk (KERN_WARNING
-                       "WF-MPU: configuration for MIDI device %d failed\n",
-                       phys_dev->devno);
-               sound_unload_mididev (phys_dev->devno);
-
-       }
-
-       /* OK, now we're configured to handle an interrupt ... */
-
-       if (request_irq (phys_dev->irq, wf_mpuintr, IRQF_DISABLED|IRQF_SHARED,
-                        "wavefront midi", phys_dev) < 0) {
-
-               printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
-                       phys_dev->irq);
-               return -1;
-
-       }
-
-       /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
-          to switch it into UART (dumb) mode, because otherwise, it
-          won't do anything at all.
-       */
-  
-       start_uart_mode ();
-
-       return phys_dev->devno;
-}
-void
-uninstall_wf_mpu (void)
-
-{
-       release_region (phys_dev->base, 2); 
-       free_irq (phys_dev->irq, phys_dev);
-       sound_unload_mididev (phys_dev->devno);
-
-       if (virt_dev->devno >= 0) {
-               sound_unload_mididev (virt_dev->devno);
-       }
-}
-
-static void
-start_uart_mode (void)
-
-{
-       int             ok, i;
-       unsigned long   flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       /* XXX fix me */
-
-       for (i = 0; i < 30000 && !output_ready (); i++);
-
-       outb (UART_MODE_ON, COMDPORT(phys_dev));
-
-       for (ok = 0, i = 50000; i > 0 && !ok; i--) {
-               if (input_avail ()) {
-                       if (read_data () == MPU_ACK) {
-                               ok = 1;
-                       }
-               }
-       }
-
-       spin_unlock_irqrestore(&lock,flags);
-}
-#endif
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
deleted file mode 100644 (file)
index 6e22472..0000000
+++ /dev/null
@@ -1,2692 +0,0 @@
-/*
- *  Copyright 1999 Jaroslav Kysela <perex@suse.cz>
- *  Copyright 2000 Alan Cox <alan@redhat.com>
- *  Copyright 2001 Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
- *  Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com>
- *
- *  Yamaha YMF7xx driver.
- *
- *  This code is a result of high-speed collision
- *  between ymfpci.c of ALSA and cs46xx.c of Linux.
- *  -- Pete Zaitcev <zaitcev@yahoo.com>; 2000/09/18
- *
- *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- *  - Use P44Slot for 44.1 playback (beware of idle buzzing in P44Slot).
- *  - 96KHz playback for DVD - use pitch of 2.0.
- *  - Retain DMA buffer on close, do not wait the end of frame.
- *  - Resolve XXX tagged questions.
- *  - Cannot play 5133Hz.
- *  - 2001/01/07 Consider if we can remove voice_lock, like so:
- *     : Allocate/deallocate voices in open/close under semafore.
- *     : We access voices in interrupt, that only for pcms that open.
- *    voice_lock around playback_prepare closes interrupts for insane duration.
- *  - Revisit the way voice_alloc is done - too confusing, overcomplicated.
- *    Should support various channel types, however.
- *  - Remove prog_dmabuf from read/write, leave it in open.
- *  - 2001/01/07 Replace the OPL3 part of CONFIG_SOUND_YMFPCI_LEGACY code with
- *    native synthesizer through a playback slot.
- *  - 2001/11/29 ac97_save_state
- *    Talk to Kai to remove ac97_save_state before it's too late!
- *  - Second AC97
- *  - Restore S/PDIF - Toshibas have it.
- *
- * Kai used pci_alloc_consistent for DMA buffer, which sounds a little
- * unconventional. However, given how small our fragments can be,
- * a little uncached access is perhaps better than endless flushing.
- * On i386 and other I/O-coherent architectures pci_alloc_consistent
- * is entirely harmless.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/soundcard.h>
-#include <linux/ac97_codec.h>
-#include <linux/sound.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# include "sound_config.h"
-# include "mpu401.h"
-#endif
-#include "ymfpci.h"
-
-/*
- * I do not believe in debug levels as I never can guess what
- * part of the code is going to be problematic in the future.
- * Don't forget to run your klogd with -c 8.
- *
- * Example (do not remove):
- * #define YMFDBG(fmt, arg...)  do{ printk(KERN_DEBUG fmt, ##arg); }while(0)
- */
-#define YMFDBGW(fmt, arg...)  /* */    /* write counts */
-#define YMFDBGI(fmt, arg...)  /* */    /* interrupts */
-#define YMFDBGX(fmt, arg...)  /* */    /* ioctl */
-
-static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice);
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank);
-static int ymf_playback_prepare(struct ymf_state *state);
-static int ymf_capture_prepare(struct ymf_state *state);
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit);
-
-static void ymfpci_aclink_reset(struct pci_dev * pci);
-static void ymfpci_disable_dsp(ymfpci_t *unit);
-static void ymfpci_download_image(ymfpci_t *codec);
-static void ymf_memload(ymfpci_t *unit);
-
-static DEFINE_SPINLOCK(ymf_devs_lock);
-static LIST_HEAD(ymf_devs);
-
-/*
- *  constants
- */
-
-static struct pci_device_id ymf_id_tbl[] = {
-#define DEV(dev, data) \
-       { PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
-               (unsigned long)data }
-       DEV (PCI_DEVICE_ID_YAMAHA_724,  "YMF724"),
-       DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"),
-       DEV (PCI_DEVICE_ID_YAMAHA_740,  "YMF740"),
-       DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"),
-       DEV (PCI_DEVICE_ID_YAMAHA_744,  "YMF744"),
-       DEV (PCI_DEVICE_ID_YAMAHA_754,  "YMF754"),
-#undef DEV
-       { }
-};
-MODULE_DEVICE_TABLE(pci, ymf_id_tbl);
-
-/*
- *  common I/O routines
- */
-
-static inline void ymfpci_writeb(ymfpci_t *codec, u32 offset, u8 val)
-{
-       writeb(val, codec->reg_area_virt + offset);
-}
-
-static inline u16 ymfpci_readw(ymfpci_t *codec, u32 offset)
-{
-       return readw(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writew(ymfpci_t *codec, u32 offset, u16 val)
-{
-       writew(val, codec->reg_area_virt + offset);
-}
-
-static inline u32 ymfpci_readl(ymfpci_t *codec, u32 offset)
-{
-       return readl(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writel(ymfpci_t *codec, u32 offset, u32 val)
-{
-       writel(val, codec->reg_area_virt + offset);
-}
-
-static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched)
-{
-       signed long end_time;
-       u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
-       
-       end_time = jiffies + 3 * (HZ / 4);
-       do {
-               if ((ymfpci_readw(codec, reg) & 0x8000) == 0)
-                       return 0;
-               if (sched) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
-       } while (end_time - (signed long)jiffies >= 0);
-       printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
-           secondary, ymfpci_readw(codec, reg));
-       return -EBUSY;
-}
-
-static void ymfpci_codec_write(struct ac97_codec *dev, u8 reg, u16 val)
-{
-       ymfpci_t *codec = dev->private_data;
-       u32 cmd;
-
-       spin_lock(&codec->ac97_lock);
-       /* XXX Do make use of dev->id */
-       ymfpci_codec_ready(codec, 0, 0);
-       cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
-       ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd);
-       spin_unlock(&codec->ac97_lock);
-}
-
-static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg)
-{
-       int i;
-
-       if (ymfpci_codec_ready(unit, 0, 0))
-               return ~0;
-       ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
-       if (ymfpci_codec_ready(unit, 0, 0))
-               return ~0;
-       if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) {
-               for (i = 0; i < 600; i++)
-                       ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-       }
-       return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-}
-
-static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
-{
-       ymfpci_t *unit = dev->private_data;
-       u16 ret;
-       
-       spin_lock(&unit->ac97_lock);
-       ret = _ymfpci_codec_read(unit, reg);
-       spin_unlock(&unit->ac97_lock);
-       
-       return ret;
-}
-
-/*
- *  Misc routines
- */
-
-/*
- * Calculate the actual sampling rate relatetively to the base clock (48kHz).
- */
-static u32 ymfpci_calc_delta(u32 rate)
-{
-       switch (rate) {
-       case 8000:      return 0x02aaab00;
-       case 11025:     return 0x03accd00;
-       case 16000:     return 0x05555500;
-       case 22050:     return 0x07599a00;
-       case 32000:     return 0x0aaaab00;
-       case 44100:     return 0x0eb33300;
-       default:        return ((rate << 16) / 48000) << 12;
-       }
-}
-
-static u32 def_rate[8] = {
-       100, 2000, 8000, 11025, 16000, 22050, 32000, 48000
-};
-
-static u32 ymfpci_calc_lpfK(u32 rate)
-{
-       u32 i;
-       static u32 val[8] = {
-               0x00570000, 0x06AA0000, 0x18B20000, 0x20930000,
-               0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000
-       };
-       
-       if (rate == 44100)
-               return 0x40000000;      /* FIXME: What's the right value? */
-       for (i = 0; i < 8; i++)
-               if (rate <= def_rate[i])
-                       return val[i];
-       return val[0];
-}
-
-static u32 ymfpci_calc_lpfQ(u32 rate)
-{
-       u32 i;
-       static u32 val[8] = {
-               0x35280000, 0x34A70000, 0x32020000, 0x31770000,
-               0x31390000, 0x31C90000, 0x33D00000, 0x40000000
-       };
-       
-       if (rate == 44100)
-               return 0x370A0000;
-       for (i = 0; i < 8; i++)
-               if (rate <= def_rate[i])
-                       return val[i];
-       return val[0];
-}
-
-static u32 ymf_calc_lend(u32 rate)
-{
-       return (rate * YMF_SAMPF) / 48000;
-}
-
-/*
- * We ever allow only a few formats, but let's be generic, for smaller surprise.
- */
-static int ymf_pcm_format_width(int format)
-{
-       static int mask16 = AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE;
-
-       if ((format & (format-1)) != 0) {
-               printk(KERN_ERR "ymfpci: format 0x%x is not a power of 2\n", format);
-               return 8;
-       }
-
-       if (format == AFMT_IMA_ADPCM) return 4;
-       if ((format & mask16) != 0) return 16;
-       return 8;
-}
-
-static void ymf_pcm_update_shift(struct ymf_pcm_format *f)
-{
-       f->shift = 0;
-       if (f->voices == 2)
-               f->shift++;
-       if (ymf_pcm_format_width(f->format) == 16)
-               f->shift++;
-}
-
-/* Are you sure 32K is not too much? See if mpg123 skips on loaded systems. */
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/*
- * Allocate DMA buffer
- */
-static int alloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-       void *rawbuf = NULL;
-       dma_addr_t dma_addr;
-       int order;
-       struct page *map, *mapend;
-
-       /* alloc as big a chunk as we can */
-       for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-               rawbuf = pci_alloc_consistent(unit->pci, PAGE_SIZE << order, &dma_addr);
-               if (rawbuf)
-                       break;
-       }
-       if (!rawbuf)
-               return -ENOMEM;
-
-#if 0
-       printk(KERN_DEBUG "ymfpci: allocated %ld (order = %d) bytes at %p\n",
-              PAGE_SIZE << order, order, rawbuf);
-#endif
-
-       dmabuf->ready  = dmabuf->mapped = 0;
-       dmabuf->rawbuf = rawbuf;
-       dmabuf->dma_addr = dma_addr;
-       dmabuf->buforder = order;
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       mapend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (map = virt_to_page(rawbuf); map <= mapend; map++)
-               set_bit(PG_reserved, &map->flags);
-
-       return 0;
-}
-
-/*
- * Free DMA buffer
- */
-static void dealloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-       struct page *map, *mapend;
-
-       if (dmabuf->rawbuf) {
-               /* undo marking the pages as reserved */
-               mapend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-               for (map = virt_to_page(dmabuf->rawbuf); map <= mapend; map++)
-                       clear_bit(PG_reserved, &map->flags);
-
-               pci_free_consistent(unit->pci, PAGE_SIZE << dmabuf->buforder,
-                   dmabuf->rawbuf, dmabuf->dma_addr);
-       }
-       dmabuf->rawbuf = NULL;
-       dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ymf_state *state, int rec)
-{
-       struct ymf_dmabuf *dmabuf;
-       int w_16;
-       unsigned bufsize;
-       unsigned long flags;
-       int redzone, redfrags;
-       int ret;
-
-       w_16 = ymf_pcm_format_width(state->format.format) == 16;
-       dmabuf = rec ? &state->rpcm.dmabuf : &state->wpcm.dmabuf;
-
-       spin_lock_irqsave(&state->unit->reg_lock, flags);
-       dmabuf->hwptr = dmabuf->swptr = 0;
-       dmabuf->total_bytes = 0;
-       dmabuf->count = 0;
-       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-       /* allocate DMA buffer if not allocated yet */
-       if (!dmabuf->rawbuf)
-               if ((ret = alloc_dmabuf(state->unit, dmabuf)))
-                       return ret;
-
-       /*
-        * Create fake fragment sizes and numbers for OSS ioctls.
-        * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT.
-        */
-       bufsize = PAGE_SIZE << dmabuf->buforder;
-       /* By default we give 4 big buffers. */
-       dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT - 2);
-       if (dmabuf->ossfragshift > 3 &&
-           dmabuf->ossfragshift < dmabuf->fragshift) {
-               /* If OSS set smaller fragments, give more smaller buffers. */
-               dmabuf->fragshift = dmabuf->ossfragshift;
-       }
-       dmabuf->fragsize = 1 << dmabuf->fragshift;
-
-       dmabuf->numfrag = bufsize >> dmabuf->fragshift;
-       dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-
-       if (dmabuf->ossmaxfrags >= 2) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-               redfrags = (redzone + dmabuf->fragsize-1) >> dmabuf->fragshift;
-
-               if (dmabuf->ossmaxfrags + redfrags < dmabuf->numfrag) {
-                       dmabuf->numfrag = dmabuf->ossmaxfrags + redfrags;
-                       dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-               }
-       }
-
-       memset(dmabuf->rawbuf, w_16 ? 0 : 0x80, dmabuf->dmasize);
-
-       /*
-        *      Now set up the ring 
-        */
-
-       /* XXX   ret = rec? cap_pre(): pbk_pre();  */
-       spin_lock_irqsave(&state->unit->voice_lock, flags);
-       if (rec) {
-               if ((ret = ymf_capture_prepare(state)) != 0) {
-                       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-                       return ret;
-               }
-       } else {
-               if ((ret = ymf_playback_prepare(state)) != 0) {
-                       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-                       return ret;
-               }
-       }
-       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-
-       /* set the ready flag for the dma buffer (this comment is not stupid) */
-       dmabuf->ready = 1;
-
-#if 0
-       printk(KERN_DEBUG "prog_dmabuf: rate %d format 0x%x,"
-           " numfrag %d fragsize %d dmasize %d\n",
-              state->format.rate, state->format.format, dmabuf->numfrag,
-              dmabuf->fragsize, dmabuf->dmasize);
-#endif
-
-       return 0;
-}
-
-static void ymf_start_dac(struct ymf_state *state)
-{
-       ymf_playback_trigger(state->unit, &state->wpcm, 1);
-}
-
-// static void ymf_start_adc(struct ymf_state *state)
-// {
-//     ymf_capture_trigger(state->unit, &state->rpcm, 1);
-// }
-
-/*
- * Wait until output is drained.
- * This does not kill the hardware for the sake of ioctls.
- */
-static void ymf_wait_dac(struct ymf_state *state)
-{
-       struct ymf_unit *unit = state->unit;
-       struct ymf_pcm *ypcm = &state->wpcm;
-       DECLARE_WAITQUEUE(waita, current);
-       unsigned long flags;
-
-       add_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (ypcm->dmabuf.count != 0 && !ypcm->running) {
-               ymf_playback_trigger(unit, ypcm, 1);
-       }
-
-#if 0
-       if (file->f_flags & O_NONBLOCK) {
-               /*
-                * XXX Our  mistake is to attach DMA buffer to state
-                * rather than to some per-device structure.
-                * Cannot skip waiting, can only make it shorter.
-                */
-       }
-#endif
-
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       while (ypcm->running) {
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-               schedule();
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-       /*
-        * This function may take up to 4 seconds to reach this point
-        * (32K circular buffer, 8000 Hz). User notices.
-        */
-}
-
-/* Can just stop, without wait. Or can we? */
-static void ymf_stop_adc(struct ymf_state *state)
-{
-       struct ymf_unit *unit = state->unit;
-       unsigned long flags;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       ymf_capture_trigger(unit, &state->rpcm, 0);
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Hardware start management
- */
-
-static void ymfpci_hw_start(ymfpci_t *unit)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (unit->start_count++ == 0) {
-               ymfpci_writel(unit, YDSXGR_MODE,
-                   ymfpci_readl(unit, YDSXGR_MODE) | 3);
-               unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-static void ymfpci_hw_stop(ymfpci_t *unit)
-{
-       unsigned long flags;
-       long timeout = 1000;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (--unit->start_count == 0) {
-               ymfpci_writel(unit, YDSXGR_MODE,
-                   ymfpci_readl(unit, YDSXGR_MODE) & ~3);
-               while (timeout-- > 0) {
-                       if ((ymfpci_readl(unit, YDSXGR_STATUS) & 2) == 0)
-                               break;
-               }
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Playback voice management
- */
-
-static int voice_alloc(ymfpci_t *codec, ymfpci_voice_type_t type, int pair, ymfpci_voice_t *rvoice[])
-{
-       ymfpci_voice_t *voice, *voice2;
-       int idx;
-
-       for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) {
-               voice = &codec->voices[idx];
-               voice2 = pair ? &codec->voices[idx+1] : NULL;
-               if (voice->use || (voice2 && voice2->use))
-                       continue;
-               voice->use = 1;
-               if (voice2)
-                       voice2->use = 1;
-               switch (type) {
-               case YMFPCI_PCM:
-                       voice->pcm = 1;
-                       if (voice2)
-                               voice2->pcm = 1;
-                       break;
-               case YMFPCI_SYNTH:
-                       voice->synth = 1;
-                       break;
-               case YMFPCI_MIDI:
-                       voice->midi = 1;
-                       break;
-               }
-               ymfpci_hw_start(codec);
-               rvoice[0] = voice;
-               if (voice2) {
-                       ymfpci_hw_start(codec);
-                       rvoice[1] = voice2;
-               }
-               return 0;
-       }
-       return -EBUSY;  /* Your audio channel is open by someone else. */
-}
-
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice)
-{
-       ymfpci_hw_stop(unit);
-       pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
-       pvoice->ypcm = NULL;
-}
-
-/*
- */
-
-static void ymf_pcm_interrupt(ymfpci_t *codec, ymfpci_voice_t *voice)
-{
-       struct ymf_pcm *ypcm;
-       int redzone;
-       int pos, delta, swptr;
-       int played, distance;
-       struct ymf_state *state;
-       struct ymf_dmabuf *dmabuf;
-       char silence;
-
-       if ((ypcm = voice->ypcm) == NULL) {
-               return;
-       }
-       if ((state = ypcm->state) == NULL) {
-               ypcm->running = 0;      // lock it
-               return;
-       }
-       dmabuf = &ypcm->dmabuf;
-       spin_lock(&codec->reg_lock);
-       if (ypcm->running) {
-               YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
-                  voice->number, codec->active_bank, dmabuf->count,
-                  le32_to_cpu(voice->bank[0].start),
-                  le32_to_cpu(voice->bank[1].start));
-               silence = (ymf_pcm_format_width(state->format.format) == 16) ?
-                   0 : 0x80;
-               /* We need actual left-hand-side redzone size here. */
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= (state->format.shift + 1);
-               swptr = dmabuf->swptr;
-
-               pos = le32_to_cpu(voice->bank[codec->active_bank].start);
-               pos <<= state->format.shift;
-               if (pos < 0 || pos >= dmabuf->dmasize) {        /* ucode bug */
-                       printk(KERN_ERR "ymfpci%d: runaway voice %d: hwptr %d=>%d dmasize %d\n",
-                           codec->dev_audio, voice->number,
-                           dmabuf->hwptr, pos, dmabuf->dmasize);
-                       pos = 0;
-               }
-               if (pos < dmabuf->hwptr) {
-                       delta = dmabuf->dmasize - dmabuf->hwptr;
-                       memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-                       delta += pos;
-                       memset(dmabuf->rawbuf, silence, pos);
-               } else {
-                       delta = pos - dmabuf->hwptr;
-                       memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-               }
-               dmabuf->hwptr = pos;
-
-               if (dmabuf->count == 0) {
-                       printk(KERN_ERR "ymfpci%d: %d: strain: hwptr %d\n",
-                           codec->dev_audio, voice->number, dmabuf->hwptr);
-                       ymf_playback_trigger(codec, ypcm, 0);
-               }
-
-               if (swptr <= pos) {
-                       distance = pos - swptr;
-               } else {
-                       distance = dmabuf->dmasize - (swptr - pos);
-               }
-               if (distance < redzone) {
-                       /*
-                        * hwptr inside redzone => DMA ran out of samples.
-                        */
-                       if (delta < dmabuf->count) {
-                               /*
-                                * Lost interrupt or other screwage.
-                                */
-                               printk(KERN_ERR "ymfpci%d: %d: lost: delta %d"
-                                   " hwptr %d swptr %d distance %d count %d\n",
-                                   codec->dev_audio, voice->number, delta,
-                                   dmabuf->hwptr, swptr, distance, dmabuf->count);
-                       } else {
-                               /*
-                                * Normal end of DMA.
-                                */
-                               YMFDBGI("ymfpci%d: %d: done: delta %d"
-                                   " hwptr %d swptr %d distance %d count %d\n",
-                                   codec->dev_audio, voice->number, delta,
-                                   dmabuf->hwptr, swptr, distance, dmabuf->count);
-                       }
-                       played = dmabuf->count;
-                       if (ypcm->running) {
-                               ymf_playback_trigger(codec, ypcm, 0);
-                       }
-               } else {
-                       /*
-                        * hwptr is chipping away towards a remote swptr.
-                        * Calculate other distance and apply it to count.
-                        */
-                       if (swptr >= pos) {
-                               distance = swptr - pos;
-                       } else {
-                               distance = dmabuf->dmasize - (pos - swptr);
-                       }
-                       if (distance < dmabuf->count) {
-                               played = dmabuf->count - distance;
-                       } else {
-                               played = 0;
-                       }
-               }
-
-               dmabuf->total_bytes += played;
-               dmabuf->count -= played;
-               if (dmabuf->count < dmabuf->dmasize / 2) {
-                       wake_up(&dmabuf->wait);
-               }
-       }
-       spin_unlock(&codec->reg_lock);
-}
-
-static void ymf_cap_interrupt(ymfpci_t *unit, struct ymf_capture *cap)
-{
-       struct ymf_pcm *ypcm;
-       int redzone;
-       struct ymf_state *state;
-       struct ymf_dmabuf *dmabuf;
-       int pos, delta;
-       int cnt;
-
-       if ((ypcm = cap->ypcm) == NULL) {
-               return;
-       }
-       if ((state = ypcm->state) == NULL) {
-               ypcm->running = 0;      // lock it
-               return;
-       }
-       dmabuf = &ypcm->dmabuf;
-       spin_lock(&unit->reg_lock);
-       if (ypcm->running) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= (state->format.shift + 1);
-
-               pos = le32_to_cpu(cap->bank[unit->active_bank].start);
-               // pos <<= state->format.shift;
-               if (pos < 0 || pos >= dmabuf->dmasize) {        /* ucode bug */
-                       printk(KERN_ERR "ymfpci%d: runaway capture %d: hwptr %d=>%d dmasize %d\n",
-                           unit->dev_audio, ypcm->capture_bank_number,
-                           dmabuf->hwptr, pos, dmabuf->dmasize);
-                       pos = 0;
-               }
-               if (pos < dmabuf->hwptr) {
-                       delta = dmabuf->dmasize - dmabuf->hwptr;
-                       delta += pos;
-               } else {
-                       delta = pos - dmabuf->hwptr;
-               }
-               dmabuf->hwptr = pos;
-
-               cnt = dmabuf->count;
-               cnt += delta;
-               if (cnt + redzone > dmabuf->dmasize) {
-                       /* Overflow - bump swptr */
-                       dmabuf->count = dmabuf->dmasize - redzone;
-                       dmabuf->swptr = dmabuf->hwptr + redzone;
-                       if (dmabuf->swptr >= dmabuf->dmasize) {
-                               dmabuf->swptr -= dmabuf->dmasize;
-                       }
-               } else {
-                       dmabuf->count = cnt;
-               }
-
-               dmabuf->total_bytes += delta;
-               if (dmabuf->count) {            /* && is_sleeping  XXX */
-                       wake_up(&dmabuf->wait);
-               }
-       }
-       spin_unlock(&unit->reg_lock);
-}
-
-static int ymf_playback_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-
-       if (ypcm->voices[0] == NULL) {
-               return -EINVAL;
-       }
-       if (cmd != 0) {
-               codec->ctrl_playback[ypcm->voices[0]->number + 1] =
-                   cpu_to_le32(ypcm->voices[0]->bank_ba);
-               if (ypcm->voices[1] != NULL)
-                       codec->ctrl_playback[ypcm->voices[1]->number + 1] =
-                           cpu_to_le32(ypcm->voices[1]->bank_ba);
-               ypcm->running = 1;
-       } else {
-               codec->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
-               if (ypcm->voices[1] != NULL)
-                       codec->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
-               ypcm->running = 0;
-       }
-       return 0;
-}
-
-static void ymf_capture_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-       u32 tmp;
-
-       if (cmd != 0) {
-               tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number);
-               ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-               ypcm->running = 1;
-       } else {
-               tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number);
-               ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-               ypcm->running = 0;
-       }
-}
-
-static int ymfpci_pcm_voice_alloc(struct ymf_pcm *ypcm, int voices)
-{
-       struct ymf_unit *unit;
-       int err;
-
-       unit = ypcm->state->unit;
-       if (ypcm->voices[1] != NULL && voices < 2) {
-               ymfpci_voice_free(unit, ypcm->voices[1]);
-               ypcm->voices[1] = NULL;
-       }
-       if (voices == 1 && ypcm->voices[0] != NULL)
-               return 0;               /* already allocated */
-       if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL)
-               return 0;               /* already allocated */
-       if (voices > 1) {
-               if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) {
-                       ymfpci_voice_free(unit, ypcm->voices[0]);
-                       ypcm->voices[0] = NULL;
-               }               
-               if ((err = voice_alloc(unit, YMFPCI_PCM, 1, ypcm->voices)) < 0)
-                       return err;
-               ypcm->voices[0]->ypcm = ypcm;
-               ypcm->voices[1]->ypcm = ypcm;
-       } else {
-               if ((err = voice_alloc(unit, YMFPCI_PCM, 0, ypcm->voices)) < 0)
-                       return err;
-               ypcm->voices[0]->ypcm = ypcm;
-       }
-       return 0;
-}
-
-static void ymf_pcm_init_voice(ymfpci_voice_t *voice, int stereo,
-    int rate, int w_16, unsigned long addr, unsigned int end, int spdif)
-{
-       u32 format;
-       u32 delta = ymfpci_calc_delta(rate);
-       u32 lpfQ = ymfpci_calc_lpfQ(rate);
-       u32 lpfK = ymfpci_calc_lpfK(rate);
-       ymfpci_playback_bank_t *bank;
-       int nbank;
-
-       /*
-        * The gain is a floating point number. According to the manual,
-        * bit 31 indicates a sign bit, bit 30 indicates an integer part,
-        * and bits [29:15] indicate a decimal fraction part. Thus,
-        * for a gain of 1.0 the constant of 0x40000000 is loaded.
-        */
-       unsigned default_gain = cpu_to_le32(0x40000000);
-
-       format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000);
-       if (stereo)
-               end >>= 1;
-       if (w_16)
-               end >>= 1;
-       for (nbank = 0; nbank < 2; nbank++) {
-               bank = &voice->bank[nbank];
-               bank->format = cpu_to_le32(format);
-               bank->loop_default = 0; /* 0-loops forever, otherwise count */
-               bank->base = cpu_to_le32(addr);
-               bank->loop_start = 0;
-               bank->loop_end = cpu_to_le32(end);
-               bank->loop_frac = 0;
-               bank->eg_gain_end = default_gain;
-               bank->lpfQ = cpu_to_le32(lpfQ);
-               bank->status = 0;
-               bank->num_of_frames = 0;
-               bank->loop_count = 0;
-               bank->start = 0;
-               bank->start_frac = 0;
-               bank->delta =
-               bank->delta_end = cpu_to_le32(delta);
-               bank->lpfK =
-               bank->lpfK_end = cpu_to_le32(lpfK);
-               bank->eg_gain = default_gain;
-               bank->lpfD1 =
-               bank->lpfD2 = 0;
-
-               bank->left_gain = 
-               bank->right_gain =
-               bank->left_gain_end =
-               bank->right_gain_end =
-               bank->eff1_gain =
-               bank->eff2_gain =
-               bank->eff3_gain =
-               bank->eff1_gain_end =
-               bank->eff2_gain_end =
-               bank->eff3_gain_end = 0;
-
-               if (!stereo) {
-                       if (!spdif) {
-                               bank->left_gain = 
-                               bank->right_gain =
-                               bank->left_gain_end =
-                               bank->right_gain_end = default_gain;
-                       } else {
-                               bank->eff2_gain =
-                               bank->eff2_gain_end =
-                               bank->eff3_gain =
-                               bank->eff3_gain_end = default_gain;
-                       }
-               } else {
-                       if (!spdif) {
-                               if ((voice->number & 1) == 0) {
-                                       bank->left_gain =
-                                       bank->left_gain_end = default_gain;
-                               } else {
-                                       bank->format |= cpu_to_le32(1);
-                                       bank->right_gain =
-                                       bank->right_gain_end = default_gain;
-                               }
-                       } else {
-                               if ((voice->number & 1) == 0) {
-                                       bank->eff2_gain =
-                                       bank->eff2_gain_end = default_gain;
-                               } else {
-                                       bank->format |= cpu_to_le32(1);
-                                       bank->eff3_gain =
-                                       bank->eff3_gain_end = default_gain;
-                               }
-                       }
-               }
-       }
-}
-
-/*
- * XXX Capture channel allocation is entirely fake at the moment.
- * We use only one channel and mark it busy as required.
- */
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank)
-{
-       struct ymf_capture *cap;
-       int cbank;
-
-       cbank = 1;              /* Only ADC slot is used for now. */
-       cap = &unit->capture[cbank];
-       if (cap->use)
-               return -EBUSY;
-       cap->use = 1;
-       *pbank = cbank;
-       return 0;
-}
-
-static int ymf_playback_prepare(struct ymf_state *state)
-{
-       struct ymf_pcm *ypcm = &state->wpcm;
-       int err, nvoice;
-
-       if ((err = ymfpci_pcm_voice_alloc(ypcm, state->format.voices)) < 0) {
-               /* Somebody started 32 mpg123's in parallel? */
-               printk(KERN_INFO "ymfpci%d: cannot allocate voice\n",
-                   state->unit->dev_audio);
-               return err;
-       }
-
-       for (nvoice = 0; nvoice < state->format.voices; nvoice++) {
-               ymf_pcm_init_voice(ypcm->voices[nvoice],
-                   state->format.voices == 2, state->format.rate,
-                   ymf_pcm_format_width(state->format.format) == 16,
-                   ypcm->dmabuf.dma_addr, ypcm->dmabuf.dmasize,
-                   ypcm->spdif);
-       }
-       return 0;
-}
-
-static int ymf_capture_prepare(struct ymf_state *state)
-{
-       ymfpci_t *unit = state->unit;
-       struct ymf_pcm *ypcm = &state->rpcm;
-       ymfpci_capture_bank_t * bank;
-       /* XXX This is confusing, gotta rename one of them banks... */
-       int nbank;              /* flip-flop bank */
-       int cbank;              /* input [super-]bank */
-       struct ymf_capture *cap;
-       u32 rate, format;
-
-       if (ypcm->capture_bank_number == -1) {
-               if (ymf_capture_alloc(unit, &cbank) != 0)
-                       return -EBUSY;
-
-               ypcm->capture_bank_number = cbank;
-
-               cap = &unit->capture[cbank];
-               cap->bank = unit->bank_capture[cbank][0];
-               cap->ypcm = ypcm;
-               ymfpci_hw_start(unit);
-       }
-
-       // ypcm->frag_size = snd_pcm_lib_transfer_fragment(substream);
-       // frag_size is replaced with nonfragged byte-aligned rolling buffer
-       rate = ((48000 * 4096) / state->format.rate) - 1;
-       format = 0;
-       if (state->format.voices == 2)
-               format |= 2;
-       if (ymf_pcm_format_width(state->format.format) == 8)
-               format |= 1;
-       switch (ypcm->capture_bank_number) {
-       case 0:
-               ymfpci_writel(unit, YDSXGR_RECFORMAT, format);
-               ymfpci_writel(unit, YDSXGR_RECSLOTSR, rate);
-               break;
-       case 1:
-               ymfpci_writel(unit, YDSXGR_ADCFORMAT, format);
-               ymfpci_writel(unit, YDSXGR_ADCSLOTSR, rate);
-               break;
-       }
-       for (nbank = 0; nbank < 2; nbank++) {
-               bank = unit->bank_capture[ypcm->capture_bank_number][nbank];
-               bank->base = cpu_to_le32(ypcm->dmabuf.dma_addr);
-               // bank->loop_end = ypcm->dmabuf.dmasize >> state->format.shift;
-               bank->loop_end = cpu_to_le32(ypcm->dmabuf.dmasize);
-               bank->start = 0;
-               bank->num_of_loops = 0;
-       }
-#if 0 /* s/pdif */
-       if (state->digital.dig_valid)
-               /*state->digital.type == SND_PCM_DIG_AES_IEC958*/
-               ymfpci_writew(codec, YDSXGR_SPDIFOUTSTATUS,
-                   state->digital.dig_status[0] | (state->digital.dig_status[1] << 8));
-#endif
-       return 0;
-}
-
-static irqreturn_t ymf_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       ymfpci_t *codec = dev_id;
-       u32 status, nvoice, mode;
-       struct ymf_voice *voice;
-       struct ymf_capture *cap;
-
-       status = ymfpci_readl(codec, YDSXGR_STATUS);
-       if (status & 0x80000000) {
-               codec->active_bank = ymfpci_readl(codec, YDSXGR_CTRLSELECT) & 1;
-               spin_lock(&codec->voice_lock);
-               for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
-                       voice = &codec->voices[nvoice];
-                       if (voice->use)
-                               ymf_pcm_interrupt(codec, voice);
-               }
-               for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
-                       cap = &codec->capture[nvoice];
-                       if (cap->use)
-                               ymf_cap_interrupt(codec, cap);
-               }
-               spin_unlock(&codec->voice_lock);
-               spin_lock(&codec->reg_lock);
-               ymfpci_writel(codec, YDSXGR_STATUS, 0x80000000);
-               mode = ymfpci_readl(codec, YDSXGR_MODE) | 2;
-               ymfpci_writel(codec, YDSXGR_MODE, mode);
-               spin_unlock(&codec->reg_lock);
-       }
-
-       status = ymfpci_readl(codec, YDSXGR_INTFLAG);
-       if (status & 1) {
-               /* timer handler */
-               ymfpci_writel(codec, YDSXGR_INTFLAG, ~0);
-       }
-       return IRQ_HANDLED;
-}
-
-static void ymf_pcm_free_substream(struct ymf_pcm *ypcm)
-{
-       unsigned long flags;
-       struct ymf_unit *unit;
-
-       unit = ypcm->state->unit;
-
-       if (ypcm->type == PLAYBACK_VOICE) {
-               spin_lock_irqsave(&unit->voice_lock, flags);
-               if (ypcm->voices[1])
-                       ymfpci_voice_free(unit, ypcm->voices[1]);
-               if (ypcm->voices[0])
-                       ymfpci_voice_free(unit, ypcm->voices[0]);
-               spin_unlock_irqrestore(&unit->voice_lock, flags);
-       } else {
-               if (ypcm->capture_bank_number != -1) {
-                       unit->capture[ypcm->capture_bank_number].use = 0;
-                       ypcm->capture_bank_number = -1;
-                       ymfpci_hw_stop(unit);
-               }
-       }
-}
-
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit)
-{
-       struct ymf_pcm *ypcm;
-       struct ymf_state *state;
-
-       if ((state = kmalloc(sizeof(struct ymf_state), GFP_KERNEL)) == NULL) {
-               goto out0;
-       }
-       memset(state, 0, sizeof(struct ymf_state));
-
-       ypcm = &state->wpcm;
-       ypcm->state = state;
-       ypcm->type = PLAYBACK_VOICE;
-       ypcm->capture_bank_number = -1;
-       init_waitqueue_head(&ypcm->dmabuf.wait);
-
-       ypcm = &state->rpcm;
-       ypcm->state = state;
-       ypcm->type = CAPTURE_AC97;
-       ypcm->capture_bank_number = -1;
-       init_waitqueue_head(&ypcm->dmabuf.wait);
-
-       state->unit = unit;
-
-       state->format.format = AFMT_U8;
-       state->format.rate = 8000;
-       state->format.voices = 1;
-       ymf_pcm_update_shift(&state->format);
-
-       return state;
-
-out0:
-       return NULL;
-}
-
-/* AES/IEC958 channel status bits */
-#define SND_PCM_AES0_PROFESSIONAL      (1<<0)  /* 0 = consumer, 1 = professional */
-#define SND_PCM_AES0_NONAUDIO          (1<<1)  /* 0 = audio, 1 = non-audio */
-#define SND_PCM_AES0_PRO_EMPHASIS      (7<<2)  /* mask - emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_NOTID        (0<<2)  /* emphasis not indicated */
-#define SND_PCM_AES0_PRO_EMPHASIS_NONE (1<<2)  /* none emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_5015 (3<<2)  /* 50/15us emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_CCITT        (7<<2)  /* CCITT J.17 emphasis */
-#define SND_PCM_AES0_PRO_FREQ_UNLOCKED (1<<5)  /* source sample frequency: 0 = locked, 1 = unlocked */
-#define SND_PCM_AES0_PRO_FS            (3<<6)  /* mask - sample frequency */
-#define SND_PCM_AES0_PRO_FS_NOTID      (0<<6)  /* fs not indicated */
-#define SND_PCM_AES0_PRO_FS_44100      (1<<6)  /* 44.1kHz */
-#define SND_PCM_AES0_PRO_FS_48000      (2<<6)  /* 48kHz */
-#define SND_PCM_AES0_PRO_FS_32000      (3<<6)  /* 32kHz */
-#define SND_PCM_AES0_CON_NOT_COPYRIGHT (1<<2)  /* 0 = copyright, 1 = not copyright */
-#define SND_PCM_AES0_CON_EMPHASIS      (7<<3)  /* mask - emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_NONE (0<<3)  /* none emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_5015 (1<<3)  /* 50/15us emphasis */
-#define SND_PCM_AES0_CON_MODE          (3<<6)  /* mask - mode */
-#define SND_PCM_AES1_PRO_MODE          (15<<0) /* mask - channel mode */
-#define SND_PCM_AES1_PRO_MODE_NOTID    (0<<0)  /* not indicated */
-#define SND_PCM_AES1_PRO_MODE_STEREOPHONIC (2<<0) /* stereophonic - ch A is left */
-#define SND_PCM_AES1_PRO_MODE_SINGLE   (4<<0)  /* single channel */
-#define SND_PCM_AES1_PRO_MODE_TWO      (8<<0)  /* two channels */
-#define SND_PCM_AES1_PRO_MODE_PRIMARY  (12<<0) /* primary/secondary */
-#define SND_PCM_AES1_PRO_MODE_BYTE3    (15<<0) /* vector to byte 3 */
-#define SND_PCM_AES1_PRO_USERBITS      (15<<4) /* mask - user bits */
-#define SND_PCM_AES1_PRO_USERBITS_NOTID        (0<<4)  /* not indicated */
-#define SND_PCM_AES1_PRO_USERBITS_192  (8<<4)  /* 192-bit structure */
-#define SND_PCM_AES1_PRO_USERBITS_UDEF (12<<4) /* user defined application */
-#define SND_PCM_AES1_CON_CATEGORY      0x7f
-#define SND_PCM_AES1_CON_GENERAL       0x00
-#define SND_PCM_AES1_CON_EXPERIMENTAL  0x40
-#define SND_PCM_AES1_CON_SOLIDMEM_MASK 0x0f
-#define SND_PCM_AES1_CON_SOLIDMEM_ID   0x08
-#define SND_PCM_AES1_CON_BROADCAST1_MASK 0x07
-#define SND_PCM_AES1_CON_BROADCAST1_ID 0x04
-#define SND_PCM_AES1_CON_DIGDIGCONV_MASK 0x07
-#define SND_PCM_AES1_CON_DIGDIGCONV_ID 0x02
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_ID 0x06
-#define SND_PCM_AES1_CON_ADC_MASK      0x1f
-#define SND_PCM_AES1_CON_ADC_ID                0x16
-#define SND_PCM_AES1_CON_BROADCAST2_MASK 0x0f
-#define SND_PCM_AES1_CON_BROADCAST2_ID 0x0e
-#define SND_PCM_AES1_CON_LASEROPT_MASK 0x07
-#define SND_PCM_AES1_CON_LASEROPT_ID   0x01
-#define SND_PCM_AES1_CON_MUSICAL_MASK  0x07
-#define SND_PCM_AES1_CON_MUSICAL_ID    0x05
-#define SND_PCM_AES1_CON_MAGNETIC_MASK 0x07
-#define SND_PCM_AES1_CON_MAGNETIC_ID   0x03
-#define SND_PCM_AES1_CON_IEC908_CD     (SND_PCM_AES1_CON_LASEROPT_ID|0x00)
-#define SND_PCM_AES1_CON_NON_IEC908_CD (SND_PCM_AES1_CON_LASEROPT_ID|0x08)
-#define SND_PCM_AES1_CON_PCM_CODER     (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x00)
-#define SND_PCM_AES1_CON_SAMPLER       (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x20)
-#define SND_PCM_AES1_CON_MIXER         (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x10)
-#define SND_PCM_AES1_CON_RATE_CONVERTER        (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x18)
-#define SND_PCM_AES1_CON_SYNTHESIZER   (SND_PCM_AES1_CON_MUSICAL_ID|0x00)
-#define SND_PCM_AES1_CON_MICROPHONE    (SND_PCM_AES1_CON_MUSICAL_ID|0x08)
-#define SND_PCM_AES1_CON_DAT           (SND_PCM_AES1_CON_MAGNETIC_ID|0x00)
-#define SND_PCM_AES1_CON_VCR           (SND_PCM_AES1_CON_MAGNETIC_ID|0x08)
-#define SND_PCM_AES1_CON_ORIGINAL      (1<<7)  /* this bits depends on the category code */
-#define SND_PCM_AES2_PRO_SBITS         (7<<0)  /* mask - sample bits */
-#define SND_PCM_AES2_PRO_SBITS_20      (2<<0)  /* 20-bit - coordination */
-#define SND_PCM_AES2_PRO_SBITS_24      (4<<0)  /* 24-bit - main audio */
-#define SND_PCM_AES2_PRO_SBITS_UDEF    (6<<0)  /* user defined application */
-#define SND_PCM_AES2_PRO_WORDLEN       (7<<3)  /* mask - source word length */
-#define SND_PCM_AES2_PRO_WORDLEN_NOTID (0<<3)  /* not indicated */
-#define SND_PCM_AES2_PRO_WORDLEN_22_18 (2<<3)  /* 22-bit or 18-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_23_19 (4<<3)  /* 23-bit or 19-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_24_20 (5<<3)  /* 24-bit or 20-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_20_16 (6<<3)  /* 20-bit or 16-bit */
-#define SND_PCM_AES2_CON_SOURCE                (15<<0) /* mask - source number */
-#define SND_PCM_AES2_CON_SOURCE_UNSPEC (0<<0)  /* unspecified */
-#define SND_PCM_AES2_CON_CHANNEL       (15<<4) /* mask - channel number */
-#define SND_PCM_AES2_CON_CHANNEL_UNSPEC        (0<<4)  /* unspecified */
-#define SND_PCM_AES3_CON_FS            (15<<0) /* mask - sample frequency */
-#define SND_PCM_AES3_CON_FS_44100      (0<<0)  /* 44.1kHz */
-#define SND_PCM_AES3_CON_FS_48000      (2<<0)  /* 48kHz */
-#define SND_PCM_AES3_CON_FS_32000      (3<<0)  /* 32kHz */
-#define SND_PCM_AES3_CON_CLOCK         (3<<4)  /* mask - clock accuracy */
-#define SND_PCM_AES3_CON_CLOCK_1000PPM (0<<4)  /* 1000 ppm */
-#define SND_PCM_AES3_CON_CLOCK_50PPM   (1<<4)  /* 50 ppm */
-#define SND_PCM_AES3_CON_CLOCK_VARIABLE        (2<<4)  /* variable pitch */
-
-/*
- * User interface
- */
-
-/*
- * in this loop, dmabuf.count signifies the amount of data that is
- * waiting to be copied to the user's buffer.  it is filled by the dma
- * machine and drained by this loop.
- */
-static ssize_t
-ymf_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf;
-       struct ymf_unit *unit = state->unit;
-       DECLARE_WAITQUEUE(waita, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;                        /* This many to go in this revolution */
-
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-               return ret;
-       ret = 0;
-
-       add_wait_queue(&dmabuf->wait, &waita);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (count > 0) {
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               swptr = dmabuf->swptr;
-               cnt = dmabuf->dmasize - swptr;
-               if (dmabuf->count < cnt)
-                       cnt = dmabuf->count;
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       /* buffer is empty, start the dma machine and wait for data to be
-                          recorded */
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       if (!state->rpcm.running) {
-                               ymf_capture_trigger(state->unit, &state->rpcm, 1);
-                       }
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       /* This isnt strictly right for the 810  but it'll do */
-                       tmo = (dmabuf->dmasize * HZ) / (state->format.rate * 2);
-                       tmo >>= state->format.shift;
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer overrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       tmo = schedule_timeout(tmo);
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (tmo == 0 && dmabuf->count == 0) {
-                               printk(KERN_ERR "ymfpci%d: recording schedule timeout, "
-                                   "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                   state->unit->dev_audio,
-                                   dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
-                                   dmabuf->hwptr, dmabuf->swptr);
-                       }
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-
-               if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       break;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       continue;
-               }
-
-               dmabuf->swptr = swptr;
-               dmabuf->count -= cnt;
-               // spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               // spin_lock_irqsave(&unit->reg_lock, flags);
-               if (!state->rpcm.running) {
-                       ymf_capture_trigger(unit, &state->rpcm, 1);
-               }
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-
-       return ret;
-}
-
-static ssize_t
-ymf_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-       struct ymf_unit *unit = state->unit;
-       DECLARE_WAITQUEUE(waita, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;                        /* This many to go in this revolution */
-       int redzone;
-       int delay;
-
-       YMFDBGW("ymf_write: count %d\n", count);
-
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-               return ret;
-       ret = 0;
-
-       /*
-        * Alan's cs46xx works without a red zone - marvel of ingenuity.
-        * We are not so brilliant... Red zone does two things:
-        *  1. allows for safe start after a pause as we have no way
-        *     to know what the actual, relentlessly advancing, hwptr is.
-        *  2. makes computations in ymf_pcm_interrupt simpler.
-        */
-       redzone = ymf_calc_lend(state->format.rate) << state->format.shift;
-       redzone *= 3;   /* 2 redzone + 1 possible uncertainty reserve. */
-
-       add_wait_queue(&dmabuf->wait, &waita);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (count > 0) {
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               if (dmabuf->count < 0) {
-                       printk(KERN_ERR
-                          "ymf_write: count %d, was legal in cs46xx\n",
-                           dmabuf->count);
-                       dmabuf->count = 0;
-               }
-               if (dmabuf->count == 0) {
-                       swptr = dmabuf->hwptr;
-                       if (state->wpcm.running) {
-                               /*
-                                * Add uncertainty reserve.
-                                */
-                               cnt = ymf_calc_lend(state->format.rate);
-                               cnt <<= state->format.shift;
-                               if ((swptr += cnt) >= dmabuf->dmasize) {
-                                       swptr -= dmabuf->dmasize;
-                               }
-                       }
-                       dmabuf->swptr = swptr;
-               } else {
-                       /*
-                        * XXX This is not right if dmabuf->count is small -
-                        * about 2*x frame size or less. We cannot count on
-                        * on appending and not causing an artefact.
-                        * Should use a variation of the count==0 case above.
-                        */
-                       swptr = dmabuf->swptr;
-               }
-               cnt = dmabuf->dmasize - swptr;
-               if (dmabuf->count + cnt > dmabuf->dmasize - redzone)
-                       cnt = (dmabuf->dmasize - redzone) - dmabuf->count;
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       YMFDBGW("ymf_write: full, count %d swptr %d\n",
-                          dmabuf->count, dmabuf->swptr);
-                       /*
-                        * buffer is full, start the dma machine and
-                        * wait for data to be played
-                        */
-                       spin_lock_irqsave(&unit->reg_lock, flags);
-                       if (!state->wpcm.running) {
-                               ymf_playback_trigger(unit, &state->wpcm, 1);
-                       }
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       break;
-               }
-
-               if ((swptr += cnt) >= dmabuf->dmasize) {
-                       swptr -= dmabuf->dmasize;
-               }
-
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       continue;
-               }
-               dmabuf->swptr = swptr;
-               dmabuf->count += cnt;
-
-               /*
-                * Start here is a bad idea - may cause startup click
-                * in /bin/play when dmabuf is not full yet.
-                * However, some broken applications do not make
-                * any use of SNDCTL_DSP_SYNC (Doom is the worst).
-                * One frame is about 5.3ms, Doom write size is 46ms.
-                */
-               delay = state->format.rate / 20;        /* 50ms */
-               delay <<= state->format.shift;
-               if (dmabuf->count >= delay && !state->wpcm.running) {
-                       ymf_playback_trigger(unit, &state->wpcm, 1);
-               }
-
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-
-       YMFDBGW("ymf_write: ret %d dmabuf.count %d\n", ret, dmabuf->count);
-       return ret;
-}
-
-static unsigned int ymf_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf;
-       int redzone;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &state->wpcm.dmabuf.wait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &state->rpcm.dmabuf.wait, wait);
-
-       spin_lock_irqsave(&state->unit->reg_lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               dmabuf = &state->rpcm.dmabuf;
-               if (dmabuf->count >= (signed)dmabuf->fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-
-               dmabuf = &state->wpcm.dmabuf;
-               if (dmabuf->mapped) {
-                       if (dmabuf->count >= (signed)dmabuf->fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       /*
-                        * Don't select unless a full fragment is available.
-                        * Otherwise artsd does GETOSPACE, sees 0, and loops.
-                        */
-                       if (dmabuf->count + redzone + dmabuf->fragsize
-                            <= dmabuf->dmasize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-       return mask;
-}
-
-static int ymf_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-       int ret;
-       unsigned long size;
-
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(state, 0)) != 0)
-                       return ret;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(state, 1)) != 0)
-                       return ret;
-       } else 
-               return -EINVAL;
-
-       if (vma->vm_pgoff != 0)
-               return -EINVAL;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << dmabuf->buforder))
-               return -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                            virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-                            size, vma->vm_page_prot))
-               return -EAGAIN;
-       dmabuf->mapped = 1;
-
-/* P3 */ printk(KERN_INFO "ymfpci: using memory mapped sound, untested!\n");
-       return 0;
-}
-
-static int ymf_ioctl(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       int redzone;
-       int val;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETVER) arg 0x%lx\n", cmd, arg);
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_RESET:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       ymf_wait_dac(state);
-                       dmabuf = &state->wpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       dmabuf->swptr = dmabuf->hwptr;
-                       dmabuf->count = dmabuf->total_bytes = 0;
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       ymf_stop_adc(state);
-                       dmabuf = &state->rpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       dmabuf->swptr = dmabuf->hwptr;
-                       dmabuf->count = dmabuf->total_bytes = 0;
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               return 0;
-
-       case SNDCTL_DSP_SYNC:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SYNC)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       dmabuf = &state->wpcm.dmabuf;
-                       if (file->f_flags & O_NONBLOCK) {
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               if (dmabuf->count != 0 && !state->wpcm.running) {
-                                       ymf_start_dac(state);
-                               }
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       } else {
-                               ymf_wait_dac(state);
-                       }
-               }
-               /* XXX What does this do for reading? dmabuf->count=0; ? */
-               return 0;
-
-       case SNDCTL_DSP_SPEED: /* set smaple rate */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val);
-               if (val >= 8000 && val <= 48000) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               dmabuf = &state->wpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.rate = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               dmabuf = &state->rpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.rate = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-               }
-               return put_user(state->format.rate, p);
-
-       /*
-        * OSS manual does not mention SNDCTL_DSP_STEREO at all.
-        * All channels are mono and if you want stereo, you
-        * play into two channels with SNDCTL_DSP_CHANNELS.
-        * However, mpg123 calls it. I wonder, why Michael Hipp used it.
-        */
-       case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(STEREO) st %d\n", cmd, val);
-               if (file->f_mode & FMODE_WRITE) {
-                       ymf_wait_dac(state); 
-                       dmabuf = &state->wpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       state->format.voices = val ? 2 : 1;
-                       ymf_pcm_update_shift(&state->format);
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       ymf_stop_adc(state);
-                       dmabuf = &state->rpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       state->format.voices = val ? 2 : 1;
-                       ymf_pcm_update_shift(&state->format);
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETBLK)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(state, 0)))
-                               return val;
-                       val = state->wpcm.dmabuf.fragsize;
-                       YMFDBGX("ymf_ioctl: GETBLK w %d\n", val);
-                       return put_user(val, p);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       if ((val = prog_dmabuf(state, 1)))
-                               return val;
-                       val = state->rpcm.dmabuf.fragsize;
-                       YMFDBGX("ymf_ioctl: GETBLK r %d\n", val);
-                       return put_user(val, p);
-               }
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETFMTS)\n", cmd);
-               return put_user(AFMT_S16_LE|AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT: /* Select sample format */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETFMT) fmt %d\n", cmd, val);
-               if (val == AFMT_S16_LE || val == AFMT_U8) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               dmabuf = &state->wpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.format = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               dmabuf = &state->rpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.format = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-               }
-               return put_user(state->format.format, p);
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val);
-               if (val != 0) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               if (val == 1 || val == 2) {
-                                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                                       dmabuf = &state->wpcm.dmabuf;
-                                       dmabuf->ready = 0;
-                                       state->format.voices = val;
-                                       ymf_pcm_update_shift(&state->format);
-                                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                               }
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               if (val == 1 || val == 2) {
-                                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                                       dmabuf = &state->rpcm.dmabuf;
-                                       dmabuf->ready = 0;
-                                       state->format.voices = val;
-                                       ymf_pcm_update_shift(&state->format);
-                                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                               }
-                       }
-               }
-               return put_user(state->format.voices, p);
-
-       case SNDCTL_DSP_POST:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd);
-               /*
-                * Quoting OSS PG:
-                *    The ioctl SNDCTL_DSP_POST is a lightweight version of
-                *    SNDCTL_DSP_SYNC. It just tells to the driver that there
-                *    is likely to be a pause in the output. This makes it
-                *    possible for the device to handle the pause more
-                *    intelligently. This ioctl doesn't block the application.
-                *
-                * The paragraph above is a clumsy way to say "flush ioctl".
-                * This ioctl is used by mpg123.
-                */
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               if (state->wpcm.dmabuf.count != 0 && !state->wpcm.running) {
-                       ymf_start_dac(state);
-               }
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n",
-                   cmd,
-                   (val >> 16) & 0xFFFF, val & 0xFFFF,
-                   (val >> 16) & 0xFFFF, val & 0xFFFF);
-               dmabuf = &state->wpcm.dmabuf;
-               dmabuf->ossfragshift = val & 0xffff;
-               dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-               if (dmabuf->ossfragshift < 4)
-                       dmabuf->ossfragshift = 4;
-               if (dmabuf->ossfragshift > 15)
-                       dmabuf->ossfragshift = 15;
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETOSPACE)\n", cmd);
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               dmabuf = &state->wpcm.dmabuf;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                       return val;
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               abinfo.fragsize = dmabuf->fragsize;
-               abinfo.bytes = dmabuf->dmasize - dmabuf->count - redzone;
-               abinfo.fragstotal = dmabuf->numfrag;
-               abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd);
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               dmabuf = &state->rpcm.dmabuf;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               abinfo.fragsize = dmabuf->fragsize;
-               abinfo.bytes = dmabuf->count;
-               abinfo.fragstotal = dmabuf->numfrag;
-               abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd);
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETCAPS)\n", cmd);
-               /* return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
-                           p); */
-               return put_user(0, p);
-
-       case SNDCTL_DSP_GETIPTR:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd);
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               dmabuf = &state->rpcm.dmabuf;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-               cinfo.ptr = dmabuf->hwptr;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n",
-                   cinfo.ptr, cinfo.bytes);
-               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd);
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               dmabuf = &state->wpcm.dmabuf;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-               cinfo.ptr = dmabuf->hwptr;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n",
-                   cinfo.ptr, cinfo.bytes);
-               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
-               return 0;               /* Always duplex */
-
-       case SOUND_PCM_READ_RATE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
-               return put_user(state->format.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_CH)\n", cmd);
-               return put_user(state->format.voices, p);
-
-       case SOUND_PCM_READ_BITS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_BITS)\n", cmd);
-               return put_user(AFMT_S16_LE, p);
-
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_WRITE_FILTER:
-       case SOUND_PCM_READ_FILTER:
-               YMFDBGX("ymf_ioctl: cmd 0x%x unsupported\n", cmd);
-               return -ENOTTY;
-
-       default:
-               /*
-                * Some programs mix up audio devices and ioctls
-                * or perhaps they expect "universal" ioctls,
-                * for instance we get SNDCTL_TMR_CONTINUE here.
-                * (mpg123 -g 100 ends here too - to be fixed.)
-                */
-               YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd);
-               break;
-       }
-       return -ENOTTY;
-}
-
-/*
- * open(2)
- * We use upper part of the minor to distinguish between soundcards.
- * Channels are opened with a clone open.
- */
-static int ymf_open(struct inode *inode, struct file *file)
-{
-       struct list_head *list;
-       ymfpci_t *unit = NULL;
-       int minor;
-       struct ymf_state *state;
-       int err;
-
-       minor = iminor(inode);
-       if ((minor & 0x0F) == 3) {      /* /dev/dspN */
-               ;
-       } else {
-               return -ENXIO;
-       }
-
-       unit = NULL;    /* gcc warns */
-       spin_lock(&ymf_devs_lock);
-       list_for_each(list, &ymf_devs) {
-               unit = list_entry(list, ymfpci_t, ymf_devs);
-               if (((unit->dev_audio ^ minor) & ~0x0F) == 0)
-                       break;
-       }
-       spin_unlock(&ymf_devs_lock);
-       if (unit == NULL)
-               return -ENODEV;
-
-       mutex_lock(&unit->open_mutex);
-
-       if ((state = ymf_state_alloc(unit)) == NULL) {
-               mutex_unlock(&unit->open_mutex);
-               return -ENOMEM;
-       }
-       list_add_tail(&state->chain, &unit->states);
-
-       file->private_data = state;
-
-       /*
-        * ymf_read and ymf_write that we borrowed from cs46xx
-        * allocate buffers with prog_dmabuf(). We call prog_dmabuf
-        * here so that in case of DMA memory exhaustion open
-        * fails rather than write.
-        *
-        * XXX prog_dmabuf allocates voice. Should allocate explicitly, above.
-        */
-       if (file->f_mode & FMODE_WRITE) {
-               if (!state->wpcm.dmabuf.ready) {
-                       if ((err = prog_dmabuf(state, 0)) != 0) {
-                               goto out_nodma;
-                       }
-               }
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!state->rpcm.dmabuf.ready) {
-                       if ((err = prog_dmabuf(state, 1)) != 0) {
-                               goto out_nodma;
-                       }
-               }
-       }
-
-#if 0 /* test if interrupts work */
-       ymfpci_writew(unit, YDSXGR_TIMERCOUNT, 0xfffe); /* ~ 680ms */
-       ymfpci_writeb(unit, YDSXGR_TIMERCTRL,
-           (YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN));
-#endif
-       mutex_unlock(&unit->open_mutex);
-
-       return nonseekable_open(inode, file);
-
-out_nodma:
-       /*
-        * XXX Broken custom: "goto out_xxx" in other place is
-        * a nestable exception, but here it is not nestable due to semaphore.
-        * XXX Doubtful technique of self-describing objects....
-        */
-       dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-       dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-       ymf_pcm_free_substream(&state->wpcm);
-       ymf_pcm_free_substream(&state->rpcm);
-
-       list_del(&state->chain);
-       kfree(state);
-
-       mutex_unlock(&unit->open_mutex);
-       return err;
-}
-
-static int ymf_release(struct inode *inode, struct file *file)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       ymfpci_t *unit = state->unit;
-
-#if 0 /* test if interrupts work */
-       ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0);
-#endif
-
-       mutex_lock(&unit->open_mutex);
-
-       /*
-        * XXX Solve the case of O_NONBLOCK close - don't deallocate here.
-        * Deallocate when unloading the driver and we can wait.
-        */
-       ymf_wait_dac(state);
-       ymf_stop_adc(state);            /* fortunately, it's immediate */
-       dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-       dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-       ymf_pcm_free_substream(&state->wpcm);
-       ymf_pcm_free_substream(&state->rpcm);
-
-       list_del(&state->chain);
-       file->private_data = NULL;      /* Can you tell I programmed Solaris */
-       kfree(state);
-
-       mutex_unlock(&unit->open_mutex);
-
-       return 0;
-}
-
-/*
- * Mixer operations are based on cs46xx.
- */
-static int ymf_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       ymfpci_t *unit;
-       int i;
-
-       spin_lock(&ymf_devs_lock);
-       list_for_each(list, &ymf_devs) {
-               unit = list_entry(list, ymfpci_t, ymf_devs);
-               for (i = 0; i < NR_AC97; i++) {
-                       if (unit->ac97_codec[i] != NULL &&
-                           unit->ac97_codec[i]->dev_mixer == minor) {
-                               spin_unlock(&ymf_devs_lock);
-                               goto match;
-                       }
-               }
-       }
-       spin_unlock(&ymf_devs_lock);
-       return -ENODEV;
-
- match:
-       file->private_data = unit->ac97_codec[i];
-
-       return nonseekable_open(inode, file);
-}
-
-static int ymf_ioctl_mixdev(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int ymf_release_mixdev(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static /*const*/ struct file_operations ymf_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = ymf_read,
-       .write          = ymf_write,
-       .poll           = ymf_poll,
-       .ioctl          = ymf_ioctl,
-       .mmap           = ymf_mmap,
-       .open           = ymf_open,
-       .release        = ymf_release,
-};
-
-static /*const*/ struct file_operations ymf_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = ymf_ioctl_mixdev,
-       .open           = ymf_open_mixdev,
-       .release        = ymf_release_mixdev,
-};
-
-/*
- */
-
-static int ymf_suspend(struct pci_dev *pcidev, pm_message_t unused)
-{
-       struct ymf_unit *unit = pci_get_drvdata(pcidev);
-       unsigned long flags;
-       struct ymf_dmabuf *dmabuf;
-       struct list_head *p;
-       struct ymf_state *state;
-       struct ac97_codec *codec;
-       int i;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-
-       unit->suspended = 1;
-
-       for (i = 0; i < NR_AC97; i++) {
-               if ((codec = unit->ac97_codec[i]) != NULL)
-                       ac97_save_state(codec);
-       }
-
-       list_for_each(p, &unit->states) {
-               state = list_entry(p, struct ymf_state, chain);
-
-               dmabuf = &state->wpcm.dmabuf;
-               dmabuf->hwptr = dmabuf->swptr = 0;
-               dmabuf->total_bytes = 0;
-               dmabuf->count = 0;
-
-               dmabuf = &state->rpcm.dmabuf;
-               dmabuf->hwptr = dmabuf->swptr = 0;
-               dmabuf->total_bytes = 0;
-               dmabuf->count = 0;
-       }
-
-       ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0);
-       ymfpci_disable_dsp(unit);
-
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-       
-       return 0;
-}
-
-static int ymf_resume(struct pci_dev *pcidev)
-{
-       struct ymf_unit *unit = pci_get_drvdata(pcidev);
-       unsigned long flags;
-       struct list_head *p;
-       struct ymf_state *state;
-       struct ac97_codec *codec;
-       int i;
-
-       ymfpci_aclink_reset(unit->pci);
-       ymfpci_codec_ready(unit, 0, 1);         /* prints diag if not ready. */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       /* XXX At this time the legacy registers are probably deprogrammed. */
-#endif
-
-       ymfpci_download_image(unit);
-
-       ymf_memload(unit);
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-
-       if (unit->start_count) {
-               ymfpci_writel(unit, YDSXGR_MODE, 3);
-               unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-       }
-
-       for (i = 0; i < NR_AC97; i++) {
-               if ((codec = unit->ac97_codec[i]) != NULL)
-                       ac97_restore_state(codec);
-       }
-
-       unit->suspended = 0;
-       list_for_each(p, &unit->states) {
-               state = list_entry(p, struct ymf_state, chain);
-               wake_up(&state->wpcm.dmabuf.wait);
-               wake_up(&state->rpcm.dmabuf.wait);
-       }
-
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-       return 0;
-}
-
-/*
- *  initialization routines
- */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-
-static int ymfpci_setup_legacy(ymfpci_t *unit, struct pci_dev *pcidev)
-{
-       int v;
-       int mpuio = -1, oplio = -1;
-
-       switch (unit->iomidi) {
-       case 0x330:
-               mpuio = 0;
-               break;
-       case 0x300:
-               mpuio = 1;
-               break;
-       case 0x332:
-               mpuio = 2;
-               break;
-       case 0x334:
-               mpuio = 3;
-               break;
-       default: ;
-       }
-
-       switch (unit->iosynth) {
-       case 0x388:
-               oplio = 0;
-               break;
-       case 0x398:
-               oplio = 1;
-               break;
-       case 0x3a0:
-               oplio = 2;
-               break;
-       case 0x3a8:
-               oplio = 3;
-               break;
-       default: ;
-       }
-
-       if (mpuio >= 0 || oplio >= 0) {
-               /* 0x0020: 1 - 10 bits of I/O address decoded, 0 - 16 bits. */
-               v = 0x001e;
-               pci_write_config_word(pcidev, PCIR_LEGCTRL, v);
-
-               switch (pcidev->device) {
-               case PCI_DEVICE_ID_YAMAHA_724:
-               case PCI_DEVICE_ID_YAMAHA_740:
-               case PCI_DEVICE_ID_YAMAHA_724F:
-               case PCI_DEVICE_ID_YAMAHA_740C:
-                       v = 0x8800;
-                       if (mpuio >= 0) { v |= mpuio<<4; }
-                       if (oplio >= 0) { v |= oplio; }
-                       pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-                       break;
-
-               case PCI_DEVICE_ID_YAMAHA_744:
-               case PCI_DEVICE_ID_YAMAHA_754:
-                       v = 0x8800;
-                       pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-                       if (oplio >= 0) {
-                               pci_write_config_word(pcidev, PCIR_OPLADR, unit->iosynth);
-                       }
-                       if (mpuio >= 0) {
-                               pci_write_config_word(pcidev, PCIR_MPUADR, unit->iomidi);
-                       }
-                       break;
-
-               default:
-                       printk(KERN_ERR "ymfpci: Unknown device ID: 0x%x\n",
-                           pcidev->device);
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static void ymfpci_aclink_reset(struct pci_dev * pci)
-{
-       u8 cmd;
-
-       /*
-        * In the 744, 754 only 0x01 exists, 0x02 is undefined.
-        * It does not seem to hurt to trip both regardless of revision.
-        */
-       pci_read_config_byte(pci, PCIR_DSXGCTRL, &cmd);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-
-       pci_write_config_word(pci, PCIR_DSXPWRCTRL1, 0);
-       pci_write_config_word(pci, PCIR_DSXPWRCTRL2, 0);
-}
-
-static void ymfpci_enable_dsp(ymfpci_t *codec)
-{
-       ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000001);
-}
-
-static void ymfpci_disable_dsp(ymfpci_t *codec)
-{
-       u32 val;
-       int timeout = 1000;
-
-       val = ymfpci_readl(codec, YDSXGR_CONFIG);
-       if (val)
-               ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000000);
-       while (timeout-- > 0) {
-               val = ymfpci_readl(codec, YDSXGR_STATUS);
-               if ((val & 0x00000002) == 0)
-                       break;
-       }
-}
-
-#include "ymfpci_image.h"
-
-static void ymfpci_download_image(ymfpci_t *codec)
-{
-       int i, ver_1e;
-       u16 ctrl;
-
-       ymfpci_writel(codec, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
-       ymfpci_disable_dsp(codec);
-       ymfpci_writel(codec, YDSXGR_MODE, 0x00010000);
-       ymfpci_writel(codec, YDSXGR_MODE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_MAPOFREC, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_MAPOFEFFECT, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0x00000000);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-
-       /* setup DSP instruction code */
-       for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
-               ymfpci_writel(codec, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);
-
-       switch (codec->pci->device) {
-       case PCI_DEVICE_ID_YAMAHA_724F:
-       case PCI_DEVICE_ID_YAMAHA_740C:
-       case PCI_DEVICE_ID_YAMAHA_744:
-       case PCI_DEVICE_ID_YAMAHA_754:
-               ver_1e = 1;
-               break;
-       default:
-               ver_1e = 0;
-       }
-
-       if (ver_1e) {
-               /* setup control instruction code */
-               for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-                       ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst1E[i]);
-       } else {
-               for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-                       ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst[i]);
-       }
-
-       ymfpci_enable_dsp(codec);
-
-       /* 0.02s sounds not too bad, we may do schedule_timeout() later. */
-       mdelay(20); /* seems we need some delay after downloading image.. */
-}
-
-static int ymfpci_memalloc(ymfpci_t *codec)
-{
-       unsigned int playback_ctrl_size;
-       unsigned int bank_size_playback;
-       unsigned int bank_size_capture;
-       unsigned int bank_size_effect;
-       unsigned int size;
-       unsigned int off;
-       char *ptr;
-       dma_addr_t pba;
-       int voice, bank;
-
-       playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
-       bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2;
-       bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2;
-       bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2;
-       codec->work_size = YDSXG_DEFAULT_WORK_SIZE;
-
-       size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
-           ((bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) +
-           ((bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) +
-           ((bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) +
-           codec->work_size;
-
-       ptr = pci_alloc_consistent(codec->pci, size + 0xff, &pba);
-       if (ptr == NULL)
-               return -ENOMEM;
-       codec->dma_area_va = ptr;
-       codec->dma_area_ba = pba;
-       codec->dma_area_size = size + 0xff;
-
-       off = (unsigned long)ptr & 0xff;
-       if (off) {
-               ptr += 0x100 - off;
-               pba += 0x100 - off;
-       }
-
-       /*
-        * Hardware requires only ptr[playback_ctrl_size] zeroed,
-        * but in our judgement it is a wrong kind of savings, so clear it all.
-        */
-       memset(ptr, 0, size);
-
-       codec->ctrl_playback = (u32 *)ptr;
-       codec->ctrl_playback_ba = pba;
-       codec->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
-       ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-       pba += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-
-       off = 0;
-       for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
-               codec->voices[voice].number = voice;
-               codec->voices[voice].bank =
-                   (ymfpci_playback_bank_t *) (ptr + off);
-               codec->voices[voice].bank_ba = pba + off;
-               off += 2 * bank_size_playback;          /* 2 banks */
-       }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       off = 0;
-       codec->bank_base_capture = pba;
-       for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
-               for (bank = 0; bank < 2; bank++) {
-                       codec->bank_capture[voice][bank] =
-                           (ymfpci_capture_bank_t *) (ptr + off);
-                       off += bank_size_capture;
-               }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       off = 0;
-       codec->bank_base_effect = pba;
-       for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
-               for (bank = 0; bank < 2; bank++) {
-                       codec->bank_effect[voice][bank] =
-                           (ymfpci_effect_bank_t *) (ptr + off);
-                       off += bank_size_effect;
-               }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       codec->work_base = pba;
-
-       return 0;
-}
-
-static void ymfpci_memfree(ymfpci_t *codec)
-{
-       ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_WORKBASE, 0);
-       ymfpci_writel(codec, YDSXGR_WORKSIZE, 0);
-       pci_free_consistent(codec->pci,
-           codec->dma_area_size, codec->dma_area_va, codec->dma_area_ba);
-}
-
-static void ymf_memload(ymfpci_t *unit)
-{
-
-       ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, unit->ctrl_playback_ba);
-       ymfpci_writel(unit, YDSXGR_RECCTRLBASE, unit->bank_base_capture);
-       ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, unit->bank_base_effect);
-       ymfpci_writel(unit, YDSXGR_WORKBASE, unit->work_base);
-       ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2);
-
-       /* S/PDIF output initialization */
-       ymfpci_writew(unit, YDSXGR_SPDIFOUTCTRL, 0);
-       ymfpci_writew(unit, YDSXGR_SPDIFOUTSTATUS,
-               SND_PCM_AES0_CON_EMPHASIS_NONE |
-               (SND_PCM_AES1_CON_ORIGINAL << 8) |
-               (SND_PCM_AES1_CON_PCM_CODER << 8));
-
-       /* S/PDIF input initialization */
-       ymfpci_writew(unit, YDSXGR_SPDIFINCTRL, 0);
-
-       /* move this volume setup to mixer */
-       ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
-       ymfpci_writel(unit, YDSXGR_BUF441OUTVOL, 0);
-       ymfpci_writel(unit, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
-       ymfpci_writel(unit, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
-}
-
-static int ymf_ac97_init(ymfpci_t *unit, int num_ac97)
-{
-       struct ac97_codec *codec;
-       u16 eid;
-
-       if ((codec = ac97_alloc_codec()) == NULL)
-               return -ENOMEM;
-
-       /* initialize some basic codec information, other fields will be filled
-          in ac97_probe_codec */
-       codec->private_data = unit;
-       codec->id = num_ac97;
-
-       codec->codec_read = ymfpci_codec_read;
-       codec->codec_write = ymfpci_codec_write;
-
-       if (ac97_probe_codec(codec) == 0) {
-               printk(KERN_ERR "ymfpci: ac97_probe_codec failed\n");
-               goto out_kfree;
-       }
-
-       eid = ymfpci_codec_read(codec, AC97_EXTENDED_ID);
-       if (eid==0xFFFF) {
-               printk(KERN_WARNING "ymfpci: no codec attached ?\n");
-               goto out_kfree;
-       }
-
-       unit->ac97_features = eid;
-
-       if ((codec->dev_mixer = register_sound_mixer(&ymf_mixer_fops, -1)) < 0) {
-               printk(KERN_ERR "ymfpci: couldn't register mixer!\n");
-               goto out_kfree;
-       }
-
-       unit->ac97_codec[num_ac97] = codec;
-
-       return 0;
- out_kfree:
-       ac97_release_codec(codec);
-       return -ENODEV;
-}
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# ifdef MODULE
-static int mpu_io;
-static int synth_io;
-module_param(mpu_io, int, 0);
-module_param(synth_io, int, 0);
-# else
-static int mpu_io     = 0x330;
-static int synth_io   = 0x388;
-# endif
-static int assigned;
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_device_id *ent)
-{
-       u16 ctrl;
-       unsigned long base;
-       ymfpci_t *codec;
-
-       int err;
-
-       if ((err = pci_enable_device(pcidev)) != 0) {
-               printk(KERN_ERR "ymfpci: pci_enable_device failed\n");
-               return err;
-       }
-       base = pci_resource_start(pcidev, 0);
-
-       if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "ymfpci: no core\n");
-               return -ENOMEM;
-       }
-       memset(codec, 0, sizeof(*codec));
-
-       spin_lock_init(&codec->reg_lock);
-       spin_lock_init(&codec->voice_lock);
-       spin_lock_init(&codec->ac97_lock);
-       mutex_init(&codec->open_mutex);
-       INIT_LIST_HEAD(&codec->states);
-       codec->pci = pcidev;
-
-       pci_read_config_byte(pcidev, PCI_REVISION_ID, &codec->rev);
-
-       if (request_mem_region(base, 0x8000, "ymfpci") == NULL) {
-               printk(KERN_ERR "ymfpci: unable to request mem region\n");
-               goto out_free;
-       }
-
-       if ((codec->reg_area_virt = ioremap(base, 0x8000)) == NULL) {
-               printk(KERN_ERR "ymfpci: unable to map registers\n");
-               goto out_release_region;
-       }
-
-       pci_set_master(pcidev);
-
-       printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n",
-           (char *)ent->driver_data, base, pcidev->irq);
-
-       ymfpci_aclink_reset(pcidev);
-       if (ymfpci_codec_ready(codec, 0, 1) < 0)
-               goto out_unmap;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       if (assigned == 0) {
-               codec->iomidi = mpu_io;
-               codec->iosynth = synth_io;
-               if (ymfpci_setup_legacy(codec, pcidev) < 0)
-                       goto out_unmap;
-               assigned = 1;
-       }
-#endif
-
-       ymfpci_download_image(codec);
-
-       if (ymfpci_memalloc(codec) < 0)
-               goto out_disable_dsp;
-       ymf_memload(codec);
-
-       if (request_irq(pcidev->irq, ymf_interrupt, IRQF_SHARED, "ymfpci", codec) != 0) {
-               printk(KERN_ERR "ymfpci: unable to request IRQ %d\n",
-                   pcidev->irq);
-               goto out_memfree;
-       }
-
-       /* register /dev/dsp */
-       if ((codec->dev_audio = register_sound_dsp(&ymf_fops, -1)) < 0) {
-               printk(KERN_ERR "ymfpci: unable to register dsp\n");
-               goto out_free_irq;
-       }
-
-       /*
-        * Poke just the primary for the moment.
-        */
-       if ((err = ymf_ac97_init(codec, 0)) != 0)
-               goto out_unregister_sound_dsp;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       codec->opl3_data.name = "ymfpci";
-       codec->mpu_data.name  = "ymfpci";
-
-       codec->opl3_data.io_base = codec->iosynth;
-       codec->opl3_data.irq     = -1;
-
-       codec->mpu_data.io_base  = codec->iomidi;
-       codec->mpu_data.irq      = -1;  /* May be different from our PCI IRQ. */
-
-       if (codec->iomidi) {
-               if (!probe_uart401(&codec->mpu_data, THIS_MODULE)) {
-                       codec->iomidi = 0;      /* XXX kludge */
-               }
-       }
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-       /* put it into driver list */
-       spin_lock(&ymf_devs_lock);
-       list_add_tail(&codec->ymf_devs, &ymf_devs);
-       spin_unlock(&ymf_devs_lock);
-       pci_set_drvdata(pcidev, codec);
-
-       return 0;
-
- out_unregister_sound_dsp:
-       unregister_sound_dsp(codec->dev_audio);
- out_free_irq:
-       free_irq(pcidev->irq, codec);
- out_memfree:
-       ymfpci_memfree(codec);
- out_disable_dsp:
-       ymfpci_disable_dsp(codec);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-       ymfpci_writel(codec, YDSXGR_STATUS, ~0);
- out_unmap:
-       iounmap(codec->reg_area_virt);
- out_release_region:
-       release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
- out_free:
-       if (codec->ac97_codec[0])
-               ac97_release_codec(codec->ac97_codec[0]);
-       return -ENODEV;
-}
-
-static void __devexit ymf_remove_one(struct pci_dev *pcidev)
-{
-       __u16 ctrl;
-       ymfpci_t *codec = pci_get_drvdata(pcidev);
-
-       /* remove from list of devices */
-       spin_lock(&ymf_devs_lock);
-       list_del(&codec->ymf_devs);
-       spin_unlock(&ymf_devs_lock);
-
-       unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer);
-       ac97_release_codec(codec->ac97_codec[0]);
-       unregister_sound_dsp(codec->dev_audio);
-       free_irq(pcidev->irq, codec);
-       ymfpci_memfree(codec);
-       ymfpci_writel(codec, YDSXGR_STATUS, ~0);
-       ymfpci_disable_dsp(codec);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-       iounmap(codec->reg_area_virt);
-       release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       if (codec->iomidi) {
-               unload_uart401(&codec->mpu_data);
-       }
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-}
-
-MODULE_AUTHOR("Jaroslav Kysela");
-MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio");
-MODULE_LICENSE("GPL");
-
-static struct pci_driver ymfpci_driver = {
-       .name           = "ymfpci",
-       .id_table       = ymf_id_tbl,
-       .probe          = ymf_probe_one,
-       .remove         = __devexit_p(ymf_remove_one),
-       .suspend        = ymf_suspend,
-       .resume         = ymf_resume
-};
-
-static int __init ymf_init_module(void)
-{
-       return pci_register_driver(&ymfpci_driver);
-}
-
-static void __exit ymf_cleanup_module (void)
-{
-       pci_unregister_driver(&ymfpci_driver);
-}
-
-module_init(ymf_init_module);
-module_exit(ymf_cleanup_module);
diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h
deleted file mode 100644 (file)
index ac1785f..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-#ifndef __YMFPCI_H
-#define __YMFPCI_H
-
-/*
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *  Definitions for Yahama YMF724/740/744/754 chips
- *
- *
- *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/config.h>
-#include <linux/mutex.h>
-
-/*
- *  Direct registers
- */
-
-/* #define YMFREG(codec, reg)          (codec->port + YDSXGR_##reg) */
-
-#define        YDSXGR_INTFLAG                  0x0004
-#define        YDSXGR_ACTIVITY                 0x0006
-#define        YDSXGR_GLOBALCTRL               0x0008
-#define        YDSXGR_ZVCTRL                   0x000A
-#define        YDSXGR_TIMERCTRL                0x0010
-#define        YDSXGR_TIMERCTRL_TEN             0x0001
-#define        YDSXGR_TIMERCTRL_TIEN            0x0002
-#define        YDSXGR_TIMERCOUNT               0x0012
-#define        YDSXGR_SPDIFOUTCTRL             0x0018
-#define        YDSXGR_SPDIFOUTSTATUS           0x001C
-#define        YDSXGR_EEPROMCTRL               0x0020
-#define        YDSXGR_SPDIFINCTRL              0x0034
-#define        YDSXGR_SPDIFINSTATUS            0x0038
-#define        YDSXGR_DSPPROGRAMDL             0x0048
-#define        YDSXGR_DLCNTRL                  0x004C
-#define        YDSXGR_GPIOININTFLAG            0x0050
-#define        YDSXGR_GPIOININTENABLE          0x0052
-#define        YDSXGR_GPIOINSTATUS             0x0054
-#define        YDSXGR_GPIOOUTCTRL              0x0056
-#define        YDSXGR_GPIOFUNCENABLE           0x0058
-#define        YDSXGR_GPIOTYPECONFIG           0x005A
-#define        YDSXGR_AC97CMDDATA              0x0060
-#define        YDSXGR_AC97CMDADR               0x0062
-#define        YDSXGR_PRISTATUSDATA            0x0064
-#define        YDSXGR_PRISTATUSADR             0x0066
-#define        YDSXGR_SECSTATUSDATA            0x0068
-#define        YDSXGR_SECSTATUSADR             0x006A
-#define        YDSXGR_SECCONFIG                0x0070
-#define        YDSXGR_LEGACYOUTVOL             0x0080
-#define        YDSXGR_LEGACYOUTVOLL            0x0080
-#define        YDSXGR_LEGACYOUTVOLR            0x0082
-#define        YDSXGR_NATIVEDACOUTVOL          0x0084
-#define        YDSXGR_NATIVEDACOUTVOLL         0x0084
-#define        YDSXGR_NATIVEDACOUTVOLR         0x0086
-#define        YDSXGR_SPDIFOUTVOL              0x0088
-#define        YDSXGR_SPDIFOUTVOLL             0x0088
-#define        YDSXGR_SPDIFOUTVOLR             0x008A
-#define        YDSXGR_AC3OUTVOL                0x008C
-#define        YDSXGR_AC3OUTVOLL               0x008C
-#define        YDSXGR_AC3OUTVOLR               0x008E
-#define        YDSXGR_PRIADCOUTVOL             0x0090
-#define        YDSXGR_PRIADCOUTVOLL            0x0090
-#define        YDSXGR_PRIADCOUTVOLR            0x0092
-#define        YDSXGR_LEGACYLOOPVOL            0x0094
-#define        YDSXGR_LEGACYLOOPVOLL           0x0094
-#define        YDSXGR_LEGACYLOOPVOLR           0x0096
-#define        YDSXGR_NATIVEDACLOOPVOL         0x0098
-#define        YDSXGR_NATIVEDACLOOPVOLL        0x0098
-#define        YDSXGR_NATIVEDACLOOPVOLR        0x009A
-#define        YDSXGR_SPDIFLOOPVOL             0x009C
-#define        YDSXGR_SPDIFLOOPVOLL            0x009E
-#define        YDSXGR_SPDIFLOOPVOLR            0x009E
-#define        YDSXGR_AC3LOOPVOL               0x00A0
-#define        YDSXGR_AC3LOOPVOLL              0x00A0
-#define        YDSXGR_AC3LOOPVOLR              0x00A2
-#define        YDSXGR_PRIADCLOOPVOL            0x00A4
-#define        YDSXGR_PRIADCLOOPVOLL           0x00A4
-#define        YDSXGR_PRIADCLOOPVOLR           0x00A6
-#define        YDSXGR_NATIVEADCINVOL           0x00A8
-#define        YDSXGR_NATIVEADCINVOLL          0x00A8
-#define        YDSXGR_NATIVEADCINVOLR          0x00AA
-#define        YDSXGR_NATIVEDACINVOL           0x00AC
-#define        YDSXGR_NATIVEDACINVOLL          0x00AC
-#define        YDSXGR_NATIVEDACINVOLR          0x00AE
-#define        YDSXGR_BUF441OUTVOL             0x00B0
-#define        YDSXGR_BUF441OUTVOLL            0x00B0
-#define        YDSXGR_BUF441OUTVOLR            0x00B2
-#define        YDSXGR_BUF441LOOPVOL            0x00B4
-#define        YDSXGR_BUF441LOOPVOLL           0x00B4
-#define        YDSXGR_BUF441LOOPVOLR           0x00B6
-#define        YDSXGR_SPDIFOUTVOL2             0x00B8
-#define        YDSXGR_SPDIFOUTVOL2L            0x00B8
-#define        YDSXGR_SPDIFOUTVOL2R            0x00BA
-#define        YDSXGR_SPDIFLOOPVOL2            0x00BC
-#define        YDSXGR_SPDIFLOOPVOL2L           0x00BC
-#define        YDSXGR_SPDIFLOOPVOL2R           0x00BE
-#define        YDSXGR_ADCSLOTSR                0x00C0
-#define        YDSXGR_RECSLOTSR                0x00C4
-#define        YDSXGR_ADCFORMAT                0x00C8
-#define        YDSXGR_RECFORMAT                0x00CC
-#define        YDSXGR_P44SLOTSR                0x00D0
-#define        YDSXGR_STATUS                   0x0100
-#define        YDSXGR_CTRLSELECT               0x0104
-#define        YDSXGR_MODE                     0x0108
-#define        YDSXGR_SAMPLECOUNT              0x010C
-#define        YDSXGR_NUMOFSAMPLES             0x0110
-#define        YDSXGR_CONFIG                   0x0114
-#define        YDSXGR_PLAYCTRLSIZE             0x0140
-#define        YDSXGR_RECCTRLSIZE              0x0144
-#define        YDSXGR_EFFCTRLSIZE              0x0148
-#define        YDSXGR_WORKSIZE                 0x014C
-#define        YDSXGR_MAPOFREC                 0x0150
-#define        YDSXGR_MAPOFEFFECT              0x0154
-#define        YDSXGR_PLAYCTRLBASE             0x0158
-#define        YDSXGR_RECCTRLBASE              0x015C
-#define        YDSXGR_EFFCTRLBASE              0x0160
-#define        YDSXGR_WORKBASE                 0x0164
-#define        YDSXGR_DSPINSTRAM               0x1000
-#define        YDSXGR_CTRLINSTRAM              0x4000
-
-#define YDSXG_AC97READCMD              0x8000
-#define YDSXG_AC97WRITECMD             0x0000
-
-#define PCIR_LEGCTRL                   0x40
-#define PCIR_ELEGCTRL                  0x42
-#define PCIR_DSXGCTRL                  0x48
-#define PCIR_DSXPWRCTRL1               0x4a
-#define PCIR_DSXPWRCTRL2               0x4e
-#define PCIR_OPLADR                    0x60
-#define PCIR_SBADR                     0x62
-#define PCIR_MPUADR                    0x64
-
-#define YDSXG_DSPLENGTH                        0x0080
-#define YDSXG_CTRLLENGTH               0x3000
-
-#define YDSXG_DEFAULT_WORK_SIZE                0x0400
-
-#define YDSXG_PLAYBACK_VOICES          64
-#define YDSXG_CAPTURE_VOICES           2
-#define YDSXG_EFFECT_VOICES            5
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97                2
-
-#define YMF_SAMPF                      256     /* Samples per frame @48000 */
-
-/*
- * The slot/voice control bank (2 of these per voice)
- */
-
-typedef struct stru_ymfpci_playback_bank {
-       u32 format;
-       u32 loop_default;
-       u32 base;                       /* 32-bit address */
-       u32 loop_start;                 /* 32-bit offset */
-       u32 loop_end;                   /* 32-bit offset */
-       u32 loop_frac;                  /* 8-bit fraction - loop_start */
-       u32 delta_end;                  /* pitch delta end */
-       u32 lpfK_end;
-       u32 eg_gain_end;
-       u32 left_gain_end;
-       u32 right_gain_end;
-       u32 eff1_gain_end;
-       u32 eff2_gain_end;
-       u32 eff3_gain_end;
-       u32 lpfQ;
-       u32 status;             /* P3: Always 0 for some reason. */
-       u32 num_of_frames;
-       u32 loop_count;
-       u32 start;              /* P3: J. reads this to know where chip is. */
-       u32 start_frac;
-       u32 delta;
-       u32 lpfK;
-       u32 eg_gain;
-       u32 left_gain;
-       u32 right_gain;
-       u32 eff1_gain;
-       u32 eff2_gain;
-       u32 eff3_gain;
-       u32 lpfD1;
-       u32 lpfD2;
-} ymfpci_playback_bank_t;
-
-typedef struct stru_ymfpci_capture_bank {
-       u32 base;                       /* 32-bit address (aligned at 4) */
-       u32 loop_end;                   /* size in BYTES (aligned at 4) */
-       u32 start;                      /* 32-bit offset */
-       u32 num_of_loops;               /* counter */
-} ymfpci_capture_bank_t;
-
-typedef struct stru_ymfpci_effect_bank {
-       u32 base;                       /* 32-bit address */
-       u32 loop_end;                   /* 32-bit offset */
-       u32 start;                      /* 32-bit offset */
-       u32 temp;
-} ymfpci_effect_bank_t;
-
-typedef struct ymf_voice ymfpci_voice_t;
-/*
- * Throughout the code Yaroslav names YMF unit pointer "codec"
- * even though it does not correspond to any codec. Must be historic.
- * We replace it with "unit" over time.
- * AC97 parts use "codec" to denote a codec, naturally.
- */
-typedef struct ymf_unit ymfpci_t;
-
-typedef enum {
-       YMFPCI_PCM,
-       YMFPCI_SYNTH,
-       YMFPCI_MIDI
-} ymfpci_voice_type_t;
-
-struct ymf_voice {
-       // ymfpci_t *codec;
-       int number;
-       char use, pcm, synth, midi;     // bool
-       ymfpci_playback_bank_t *bank;
-       struct ymf_pcm *ypcm;
-       dma_addr_t bank_ba;
-};
-
-struct ymf_capture {
-       // struct ymf_unit *unit;
-       int use;
-       ymfpci_capture_bank_t *bank;
-       struct ymf_pcm *ypcm;
-};
-
-struct ymf_unit {
-       u8 rev;                         /* PCI revision */
-       void __iomem *reg_area_virt;
-       void *dma_area_va;
-       dma_addr_t dma_area_ba;
-       unsigned int dma_area_size;
-
-       dma_addr_t bank_base_capture;
-       dma_addr_t bank_base_effect;
-       dma_addr_t work_base;
-       unsigned int work_size;
-
-       u32 *ctrl_playback;
-       dma_addr_t ctrl_playback_ba;
-       ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
-       ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
-       ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
-
-       int start_count;
-       int suspended;
-
-       u32 active_bank;
-       struct ymf_voice voices[YDSXG_PLAYBACK_VOICES];
-       struct ymf_capture capture[YDSXG_CAPTURE_VOICES];
-
-       struct ac97_codec *ac97_codec[NR_AC97];
-       u16 ac97_features;
-
-       struct pci_dev *pci;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       /* legacy hardware resources */
-       unsigned int iosynth, iomidi;
-       struct address_info opl3_data, mpu_data;
-#endif
-
-       spinlock_t reg_lock;
-       spinlock_t voice_lock;
-       spinlock_t ac97_lock;
-
-       /* soundcore stuff */
-       int dev_audio;
-       struct mutex open_mutex;
-
-       struct list_head ymf_devs;
-       struct list_head states;        /* List of states for this unit */
-};
-
-struct ymf_dmabuf {
-       dma_addr_t dma_addr;
-       void *rawbuf;
-       unsigned buforder;
-
-       /* OSS buffer management stuff */
-       unsigned numfrag;
-       unsigned fragshift;
-
-       /* our buffer acts like a circular ring */
-       unsigned hwptr;         /* where dma last started */
-       unsigned swptr;         /* where driver last clear/filled */
-       int count;              /* fill count */
-       unsigned total_bytes;   /* total bytes dmaed by hardware */
-
-       wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */
-
-       /* redundant, but makes calculations easier */
-       unsigned fragsize;
-       unsigned dmasize;       /* Total rawbuf[] size */
-
-       /* OSS stuff */
-       unsigned mapped:1;
-       unsigned ready:1;
-       unsigned ossfragshift;
-       int ossmaxfrags;
-       unsigned subdivision;
-};
-
-struct ymf_pcm_format {
-       int format;                     /* OSS format */
-       int rate;                       /* rate in Hz */
-       int voices;                     /* number of voices */
-       int shift;                      /* redundant, computed from the above */
-};
-
-typedef enum {
-       PLAYBACK_VOICE,
-       CAPTURE_REC,
-       CAPTURE_AC97,
-       EFFECT_DRY_LEFT,
-       EFFECT_DRY_RIGHT,
-       EFFECT_EFF1,
-       EFFECT_EFF2,
-       EFFECT_EFF3
-} ymfpci_pcm_type_t;
-
-/* This is variant record, but we hate unions. Little waste on pointers []. */
-struct ymf_pcm {
-       ymfpci_pcm_type_t type;
-       struct ymf_state *state;
-
-       ymfpci_voice_t *voices[2];
-       int capture_bank_number;
-
-       struct ymf_dmabuf dmabuf;
-       int running;
-       int spdif;
-};
-
-/*
- * "Software" or virtual channel, an instance of opened /dev/dsp.
- * It may have two physical channels (pcms) for duplex operations.
- */
-
-struct ymf_state {
-       struct list_head chain;
-       struct ymf_unit *unit;                  /* backpointer */
-       struct ymf_pcm rpcm, wpcm;
-       struct ymf_pcm_format format;
-};
-
-#endif                         /* __YMFPCI_H */
diff --git a/sound/oss/ymfpci_image.h b/sound/oss/ymfpci_image.h
deleted file mode 100644 (file)
index 112f2ff..0000000
+++ /dev/null
@@ -1,1565 +0,0 @@
-#ifndef _HWMCODE_
-#define _HWMCODE_
-
-static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
-       0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
-       0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
-       0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
-       0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-
-static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
-       0x000007, 0x240007, 0x0C0007, 0x1C0007,
-       0x060007, 0x700002, 0x000020, 0x030040,
-       0x007104, 0x004286, 0x030040, 0x000F0D,
-       0x000810, 0x20043A, 0x000282, 0x00020D,
-       0x000810, 0x20043A, 0x001282, 0x200E82,
-       0x001A82, 0x032D0D, 0x000810, 0x10043A,
-       0x02D38D, 0x000810, 0x18043A, 0x00010D,
-       0x020015, 0x0000FD, 0x000020, 0x038860,
-       0x039060, 0x038060, 0x038040, 0x038040,
-       0x038040, 0x018040, 0x000A7D, 0x038040,
-       0x038040, 0x018040, 0x200402, 0x000882,
-       0x08001A, 0x000904, 0x015986, 0x000007,
-       0x260007, 0x000007, 0x000007, 0x018A06,
-       0x000007, 0x030C8D, 0x000810, 0x18043A,
-       0x260007, 0x00087D, 0x018042, 0x00160A,
-       0x04A206, 0x000007, 0x00218D, 0x000810,
-       0x08043A, 0x21C206, 0x000007, 0x0007FD,
-       0x018042, 0x08000A, 0x000904, 0x029386,
-       0x000195, 0x090D04, 0x000007, 0x000820,
-       0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
-       0x032206, 0x018040, 0x000A7D, 0x038042,
-       0x13804A, 0x18000A, 0x001820, 0x059060,
-       0x058860, 0x018040, 0x0000FD, 0x018042,
-       0x70000A, 0x000115, 0x071144, 0x032386,
-       0x030000, 0x007020, 0x034A06, 0x018040,
-       0x00348D, 0x000810, 0x08043A, 0x21EA06,
-       0x000007, 0x02D38D, 0x000810, 0x18043A,
-       0x018206, 0x000007, 0x240007, 0x000F8D,
-       0x000810, 0x00163A, 0x002402, 0x005C02,
-       0x0028FD, 0x000020, 0x018040, 0x08000D,
-       0x000815, 0x510984, 0x000007, 0x00004D,
-       0x000E5D, 0x000E02, 0x00418D, 0x000810,
-       0x08043A, 0x2C8A06, 0x000007, 0x00008D,
-       0x000924, 0x000F02, 0x00458D, 0x000810,
-       0x08043A, 0x2C8A06, 0x000007, 0x00387D,
-       0x018042, 0x08000A, 0x001015, 0x010984,
-       0x018386, 0x000007, 0x01AA06, 0x000007,
-       0x0008FD, 0x018042, 0x18000A, 0x001904,
-       0x218086, 0x280007, 0x001810, 0x28043A,
-       0x280C02, 0x00000D, 0x000810, 0x28143A,
-       0x08808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00020D, 0x189904, 0x000007,
-       0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x055A86, 0x000007,
-       0x000100, 0x000A20, 0x00047D, 0x018040,
-       0x018042, 0x20000A, 0x003015, 0x012144,
-       0x034986, 0x000007, 0x002104, 0x034986,
-       0x000007, 0x000F8D, 0x000810, 0x280C3A,
-       0x023944, 0x06C986, 0x000007, 0x001810,
-       0x28043A, 0x08810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x002810, 0x78003A,
-       0x00688D, 0x000810, 0x08043A, 0x288A06,
-       0x000007, 0x00400D, 0x001015, 0x189904,
-       0x292904, 0x393904, 0x000007, 0x060206,
-       0x000007, 0x0004F5, 0x00007D, 0x000020,
-       0x00008D, 0x010860, 0x018040, 0x00047D,
-       0x038042, 0x21804A, 0x18000A, 0x021944,
-       0x215886, 0x000007, 0x004075, 0x71F104,
-       0x000007, 0x010042, 0x28000A, 0x002904,
-       0x212086, 0x000007, 0x003C0D, 0x30A904,
-       0x000007, 0x00077D, 0x018042, 0x08000A,
-       0x000904, 0x07DA86, 0x00057D, 0x002820,
-       0x03B060, 0x07F206, 0x018040, 0x003020,
-       0x03A860, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x07FA86, 0x000007,
-       0x00057D, 0x018042, 0x28040A, 0x000E8D,
-       0x000810, 0x280C3A, 0x00000D, 0x000810,
-       0x28143A, 0x09000D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x003DFD, 0x000020,
-       0x018040, 0x00107D, 0x008D8D, 0x000810,
-       0x08043A, 0x288A06, 0x000007, 0x000815,
-       0x08001A, 0x010984, 0x095186, 0x00137D,
-       0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x038A60, 0x018040, 0x007FBD, 0x383DC4,
-       0x000007, 0x001A7D, 0x001375, 0x018042,
-       0x09004A, 0x10000A, 0x0B8D04, 0x139504,
-       0x000007, 0x000820, 0x019060, 0x001104,
-       0x212086, 0x010040, 0x0017FD, 0x018042,
-       0x08000A, 0x000904, 0x212286, 0x000007,
-       0x00197D, 0x038042, 0x09804A, 0x10000A,
-       0x000924, 0x001664, 0x0011FD, 0x038042,
-       0x2B804A, 0x19804A, 0x00008D, 0x218944,
-       0x000007, 0x002244, 0x0AE186, 0x000007,
-       0x001A64, 0x002A24, 0x00197D, 0x080102,
-       0x100122, 0x000820, 0x039060, 0x018040,
-       0x003DFD, 0x00008D, 0x000820, 0x018040,
-       0x001375, 0x001A7D, 0x010042, 0x09804A,
-       0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
-       0x309144, 0x000007, 0x00060D, 0x000A15,
-       0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
-       0x000464, 0x01B3E4, 0x0232E4, 0x000464,
-       0x000464, 0x000464, 0x000464, 0x00040D,
-       0x08B1C4, 0x000007, 0x000820, 0x000BF5,
-       0x030040, 0x00197D, 0x038042, 0x09804A,
-       0x000A24, 0x08000A, 0x080E64, 0x000007,
-       0x100122, 0x000820, 0x031060, 0x010040,
-       0x0064AC, 0x00027D, 0x000020, 0x018040,
-       0x00107D, 0x018042, 0x0011FD, 0x3B804A,
-       0x09804A, 0x20000A, 0x000095, 0x1A1144,
-       0x00A144, 0x0D2086, 0x00040D, 0x00B984,
-       0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
-       0x09804A, 0x28000A, 0x000095, 0x010924,
-       0x002A64, 0x0D1186, 0x000007, 0x002904,
-       0x0D2286, 0x000007, 0x0D2A06, 0x080002,
-       0x00008D, 0x00387D, 0x000820, 0x018040,
-       0x00127D, 0x018042, 0x10000A, 0x003904,
-       0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
-       0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
-       0x000015, 0x00082D, 0x02C78D, 0x000820,
-       0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
-       0x0E7186, 0x400025, 0x00008D, 0x110944,
-       0x000007, 0x00018D, 0x109504, 0x000007,
-       0x009164, 0x000424, 0x000424, 0x000424,
-       0x100102, 0x280002, 0x02C68D, 0x000820,
-       0x0EC206, 0x00018D, 0x00042D, 0x00008D,
-       0x109504, 0x000007, 0x00020D, 0x109184,
-       0x000007, 0x02C70D, 0x000820, 0x00008D,
-       0x0038FD, 0x018040, 0x003BFD, 0x001020,
-       0x03A860, 0x000815, 0x313184, 0x212184,
-       0x000007, 0x03B060, 0x03A060, 0x018040,
-       0x0022FD, 0x000095, 0x010924, 0x000424,
-       0x000424, 0x001264, 0x100102, 0x000820,
-       0x039060, 0x018040, 0x001924, 0x00FB8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x000424,
-       0x000424, 0x00117D, 0x018042, 0x08000A,
-       0x000A24, 0x280502, 0x280C02, 0x09800D,
-       0x000820, 0x0002FD, 0x018040, 0x200007,
-       0x0022FD, 0x018042, 0x08000A, 0x000095,
-       0x280DC4, 0x011924, 0x00197D, 0x018042,
-       0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
-       0x113144, 0x0A8D04, 0x000007, 0x080A44,
-       0x129504, 0x000007, 0x0023FD, 0x001020,
-       0x038040, 0x101244, 0x000007, 0x000820,
-       0x039060, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x10FA86, 0x000007,
-       0x003BFD, 0x000100, 0x000A10, 0x0B807A,
-       0x13804A, 0x090984, 0x000007, 0x000095,
-       0x013D04, 0x118086, 0x10000A, 0x100002,
-       0x090984, 0x000007, 0x038042, 0x11804A,
-       0x090D04, 0x000007, 0x10000A, 0x090D84,
-       0x000007, 0x00257D, 0x000820, 0x018040,
-       0x00010D, 0x000810, 0x28143A, 0x00127D,
-       0x018042, 0x20000A, 0x00197D, 0x018042,
-       0x00117D, 0x31804A, 0x10000A, 0x003124,
-       0x01280D, 0x00397D, 0x000820, 0x058040,
-       0x038042, 0x09844A, 0x000606, 0x08040A,
-       0x300102, 0x003124, 0x000424, 0x000424,
-       0x001224, 0x280502, 0x001A4C, 0x130186,
-       0x700002, 0x00002D, 0x030000, 0x00387D,
-       0x018042, 0x10000A, 0x132A06, 0x002124,
-       0x0000AD, 0x100002, 0x00010D, 0x000924,
-       0x006B24, 0x01368D, 0x00397D, 0x000820,
-       0x058040, 0x038042, 0x09844A, 0x000606,
-       0x08040A, 0x003264, 0x00008D, 0x000A24,
-       0x001020, 0x00227D, 0x018040, 0x013C0D,
-       0x000810, 0x08043A, 0x29D206, 0x000007,
-       0x002820, 0x00207D, 0x018040, 0x00117D,
-       0x038042, 0x13804A, 0x33800A, 0x00387D,
-       0x018042, 0x08000A, 0x000904, 0x163A86,
-       0x000007, 0x00008D, 0x030964, 0x01478D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x380102,
-       0x000424, 0x000424, 0x001224, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x14A286,
-       0x000007, 0x280502, 0x001A4C, 0x163986,
-       0x000007, 0x032164, 0x00632C, 0x003DFD,
-       0x018042, 0x08000A, 0x000095, 0x090904,
-       0x000007, 0x000820, 0x001A4C, 0x156186,
-       0x018040, 0x030000, 0x157A06, 0x002124,
-       0x00010D, 0x000924, 0x006B24, 0x015B8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x003A64,
-       0x000095, 0x001224, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x15DA86, 0x000007,
-       0x01628D, 0x000810, 0x08043A, 0x29D206,
-       0x000007, 0x14D206, 0x000007, 0x007020,
-       0x08010A, 0x10012A, 0x0020FD, 0x038860,
-       0x039060, 0x018040, 0x00227D, 0x018042,
-       0x003DFD, 0x08000A, 0x31844A, 0x000904,
-       0x16D886, 0x18008B, 0x00008D, 0x189904,
-       0x00312C, 0x17AA06, 0x000007, 0x00324C,
-       0x173386, 0x000007, 0x001904, 0x173086,
-       0x000007, 0x000095, 0x199144, 0x00222C,
-       0x003124, 0x00636C, 0x000E3D, 0x001375,
-       0x000BFD, 0x010042, 0x09804A, 0x10000A,
-       0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
-       0x000007, 0x00008D, 0x189904, 0x00226C,
-       0x00322C, 0x30050A, 0x301DAB, 0x002083,
-       0x0018FD, 0x018042, 0x08000A, 0x018924,
-       0x300502, 0x001083, 0x001875, 0x010042,
-       0x10000A, 0x00008D, 0x010924, 0x001375,
-       0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
-       0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
-       0x305C8B, 0x006083, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x187A86, 0x000007,
-       0x001E2D, 0x0005FD, 0x018042, 0x08000A,
-       0x028924, 0x280502, 0x00060D, 0x000810,
-       0x280C3A, 0x00008D, 0x000810, 0x28143A,
-       0x0A808D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x001275, 0x030042, 0x21004A,
-       0x00008D, 0x1A0944, 0x000007, 0x01980D,
-       0x000810, 0x08043A, 0x2B2206, 0x000007,
-       0x0001F5, 0x030042, 0x0D004A, 0x10000A,
-       0x089144, 0x000007, 0x000820, 0x010040,
-       0x0025F5, 0x0A3144, 0x000007, 0x000820,
-       0x032860, 0x030040, 0x00217D, 0x038042,
-       0x0B804A, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x00008D, 0x000124, 0x00012C,
-       0x000E64, 0x001A64, 0x00636C, 0x08010A,
-       0x10012A, 0x000820, 0x031060, 0x030040,
-       0x0020FD, 0x018042, 0x08000A, 0x00227D,
-       0x018042, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x00197D, 0x018042, 0x08000A,
-       0x0022FD, 0x038042, 0x10000A, 0x000820,
-       0x031060, 0x030040, 0x090D04, 0x000007,
-       0x000820, 0x030040, 0x038042, 0x0B804A,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x038042, 0x13804A, 0x19804A, 0x110D04,
-       0x198D04, 0x000007, 0x08000A, 0x001020,
-       0x031860, 0x030860, 0x030040, 0x00008D,
-       0x0B0944, 0x000007, 0x000820, 0x010040,
-       0x0005F5, 0x030042, 0x08000A, 0x000820,
-       0x010040, 0x0000F5, 0x010042, 0x08000A,
-       0x000904, 0x1C6086, 0x001E75, 0x030042,
-       0x01044A, 0x000C0A, 0x1C7206, 0x000007,
-       0x000402, 0x000C02, 0x00177D, 0x001AF5,
-       0x018042, 0x03144A, 0x031C4A, 0x03244A,
-       0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
-       0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
-       0x030042, 0x0B004A, 0x1B804A, 0x13804A,
-       0x20000A, 0x089144, 0x19A144, 0x0389E4,
-       0x0399EC, 0x005502, 0x005D0A, 0x030042,
-       0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-       0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-       0x006502, 0x006D0A, 0x030042, 0x0B004A,
-       0x19004A, 0x2B804A, 0x13804A, 0x21804A,
-       0x30000A, 0x089144, 0x19A144, 0x2AB144,
-       0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
-       0x03A9E4, 0x000702, 0x00107D, 0x000415,
-       0x018042, 0x08000A, 0x0109E4, 0x000F02,
-       0x002AF5, 0x0019FD, 0x010042, 0x09804A,
-       0x10000A, 0x000934, 0x001674, 0x0029F5,
-       0x010042, 0x10000A, 0x00917C, 0x002075,
-       0x010042, 0x08000A, 0x000904, 0x1ED286,
-       0x0026F5, 0x0027F5, 0x030042, 0x09004A,
-       0x10000A, 0x000A3C, 0x00167C, 0x001A75,
-       0x000BFD, 0x010042, 0x51804A, 0x48000A,
-       0x160007, 0x001075, 0x010042, 0x282C0A,
-       0x281D12, 0x282512, 0x001F32, 0x1E0007,
-       0x0E0007, 0x001975, 0x010042, 0x002DF5,
-       0x0D004A, 0x10000A, 0x009144, 0x1FB286,
-       0x010042, 0x28340A, 0x000E5D, 0x00008D,
-       0x000375, 0x000820, 0x010040, 0x05D2F4,
-       0x54D104, 0x00735C, 0x205386, 0x000007,
-       0x0C0007, 0x080007, 0x0A0007, 0x02040D,
-       0x000810, 0x08043A, 0x332206, 0x000007,
-       0x205A06, 0x000007, 0x080007, 0x002275,
-       0x010042, 0x20000A, 0x002104, 0x212086,
-       0x001E2D, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x209286, 0x000007, 0x002010,
-       0x30043A, 0x00057D, 0x0180C3, 0x08000A,
-       0x028924, 0x280502, 0x280C02, 0x0A810D,
-       0x000820, 0x0002F5, 0x010040, 0x220007,
-       0x0004FD, 0x018042, 0x70000A, 0x030000,
-       0x007020, 0x06FA06, 0x018040, 0x02180D,
-       0x000810, 0x08043A, 0x2B2206, 0x000007,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x218A86, 0x000007, 0x01F206, 0x000007,
-       0x000875, 0x0009FD, 0x00010D, 0x220A06,
-       0x000295, 0x000B75, 0x00097D, 0x00000D,
-       0x000515, 0x010042, 0x18000A, 0x001904,
-       0x287886, 0x0006F5, 0x001020, 0x010040,
-       0x0004F5, 0x000820, 0x010040, 0x000775,
-       0x010042, 0x09804A, 0x10000A, 0x001124,
-       0x000904, 0x22BA86, 0x000815, 0x080102,
-       0x101204, 0x22DA06, 0x000575, 0x081204,
-       0x000007, 0x100102, 0x000575, 0x000425,
-       0x021124, 0x100102, 0x000820, 0x031060,
-       0x010040, 0x001924, 0x287886, 0x00008D,
-       0x000464, 0x009D04, 0x278886, 0x180102,
-       0x000575, 0x010042, 0x28040A, 0x00018D,
-       0x000924, 0x280D02, 0x00000D, 0x000924,
-       0x281502, 0x10000D, 0x000820, 0x0002F5,
-       0x010040, 0x200007, 0x001175, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x23C286,
-       0x000007, 0x000100, 0x080B20, 0x130B60,
-       0x1B0B60, 0x030A60, 0x010040, 0x050042,
-       0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
-       0x0006F5, 0x010042, 0x28140A, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x24CA86, 0x004015, 0x000095, 0x010D04,
-       0x24B886, 0x100022, 0x10002A, 0x24E206,
-       0x000007, 0x333104, 0x2AA904, 0x000007,
-       0x032124, 0x280502, 0x001124, 0x000424,
-       0x000424, 0x003224, 0x00292C, 0x00636C,
-       0x25F386, 0x000007, 0x02B164, 0x000464,
-       0x000464, 0x00008D, 0x000A64, 0x280D02,
-       0x10008D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x00008D, 0x38B904, 0x000007,
-       0x03296C, 0x30010A, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x25BA86, 0x000007,
-       0x02312C, 0x28050A, 0x00008D, 0x01096C,
-       0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x001124, 0x000424,
-       0x000424, 0x003224, 0x300102, 0x032944,
-       0x267A86, 0x000007, 0x300002, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x26C086, 0x003124, 0x000464, 0x300102,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x26CA86, 0x000007, 0x003124, 0x300502,
-       0x003924, 0x300583, 0x000883, 0x0005F5,
-       0x010042, 0x28040A, 0x00008D, 0x008124,
-       0x280D02, 0x00008D, 0x008124, 0x281502,
-       0x10018D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x001025, 0x000575, 0x030042,
-       0x09004A, 0x10000A, 0x0A0904, 0x121104,
-       0x000007, 0x001020, 0x050860, 0x050040,
-       0x0006FD, 0x018042, 0x09004A, 0x10000A,
-       0x0000A5, 0x0A0904, 0x121104, 0x000007,
-       0x000820, 0x019060, 0x010040, 0x0002F5,
-       0x010042, 0x08000A, 0x000904, 0x284286,
-       0x000007, 0x230A06, 0x000007, 0x000606,
-       0x000007, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x289286, 0x000007, 0x000100,
-       0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
-       0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
-       0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
-       0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
-       0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
-       0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
-       0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
-       0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
-       0x000606, 0x018040, 0x00008D, 0x000A64,
-       0x280D02, 0x000A24, 0x00027D, 0x018042,
-       0x10000A, 0x001224, 0x0003FD, 0x018042,
-       0x08000A, 0x000904, 0x2A8286, 0x000007,
-       0x00018D, 0x000A24, 0x000464, 0x000464,
-       0x080102, 0x000924, 0x000424, 0x000424,
-       0x100102, 0x02000D, 0x009144, 0x2AD986,
-       0x000007, 0x0001FD, 0x018042, 0x08000A,
-       0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
-       0x000820, 0x0002FD, 0x018040, 0x200007,
-       0x00027D, 0x001020, 0x000606, 0x018040,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x2B2A86, 0x000007, 0x00037D, 0x018042,
-       0x08000A, 0x000904, 0x2B5A86, 0x000007,
-       0x000075, 0x002E7D, 0x010042, 0x0B804A,
-       0x000020, 0x000904, 0x000686, 0x010040,
-       0x31844A, 0x30048B, 0x000883, 0x00008D,
-       0x000810, 0x28143A, 0x00008D, 0x000810,
-       0x280C3A, 0x000675, 0x010042, 0x08000A,
-       0x003815, 0x010924, 0x280502, 0x0B000D,
-       0x000820, 0x0002F5, 0x010040, 0x000606,
-       0x220007, 0x000464, 0x000464, 0x000606,
-       0x000007, 0x000134, 0x007F8D, 0x00093C,
-       0x281D12, 0x282512, 0x001F32, 0x0E0007,
-       0x00010D, 0x00037D, 0x000820, 0x018040,
-       0x05D2F4, 0x000007, 0x080007, 0x00037D,
-       0x018042, 0x08000A, 0x000904, 0x2D0286,
-       0x000007, 0x000606, 0x000007, 0x000007,
-       0x000012, 0x100007, 0x320007, 0x600007,
-       0x100080, 0x48001A, 0x004904, 0x2D6186,
-       0x000007, 0x001210, 0x58003A, 0x000145,
-       0x5C5D04, 0x000007, 0x000080, 0x48001A,
-       0x004904, 0x2DB186, 0x000007, 0x001210,
-       0x50003A, 0x005904, 0x2E0886, 0x000045,
-       0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
-       0x004224, 0x500102, 0x200502, 0x000082,
-       0x40001A, 0x004104, 0x2E3986, 0x000007,
-       0x003865, 0x40001A, 0x004020, 0x00104D,
-       0x04C184, 0x301B86, 0x000040, 0x040007,
-       0x000165, 0x000145, 0x004020, 0x000040,
-       0x000765, 0x080080, 0x40001A, 0x004104,
-       0x2EC986, 0x000007, 0x001210, 0x40003A,
-       0x004104, 0x2F2286, 0x00004D, 0x0000CD,
-       0x004810, 0x20043A, 0x000882, 0x40001A,
-       0x004104, 0x2F3186, 0x000007, 0x004820,
-       0x005904, 0x300886, 0x000040, 0x0007E5,
-       0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
-       0x4216E0, 0x021260, 0x000040, 0x000032,
-       0x400075, 0x00007D, 0x07D574, 0x200512,
-       0x000082, 0x40001A, 0x004104, 0x2FE186,
-       0x000007, 0x037206, 0x640007, 0x060007,
-       0x0000E5, 0x000020, 0x000040, 0x000A65,
-       0x000020, 0x020040, 0x020040, 0x000040,
-       0x000165, 0x000042, 0x70000A, 0x007104,
-       0x30A286, 0x000007, 0x018206, 0x640007,
-       0x050000, 0x007020, 0x000040, 0x037206,
-       0x640007, 0x000007, 0x00306D, 0x028860,
-       0x029060, 0x08000A, 0x028860, 0x008040,
-       0x100012, 0x00100D, 0x009184, 0x314186,
-       0x000E0D, 0x009184, 0x325186, 0x000007,
-       0x300007, 0x001020, 0x003B6D, 0x008040,
-       0x000080, 0x08001A, 0x000904, 0x316186,
-       0x000007, 0x001220, 0x000DED, 0x008040,
-       0x008042, 0x10000A, 0x40000D, 0x109544,
-       0x000007, 0x001020, 0x000DED, 0x008040,
-       0x008042, 0x20040A, 0x000082, 0x08001A,
-       0x000904, 0x31F186, 0x000007, 0x003B6D,
-       0x008042, 0x08000A, 0x000E15, 0x010984,
-       0x329B86, 0x600007, 0x08001A, 0x000C15,
-       0x010984, 0x328386, 0x000020, 0x1A0007,
-       0x0002ED, 0x008040, 0x620007, 0x00306D,
-       0x028042, 0x0A804A, 0x000820, 0x0A804A,
-       0x000606, 0x10804A, 0x000007, 0x282512,
-       0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
-       0x000786, 0x000007, 0x0C0007, 0x0A0007,
-       0x1C0007, 0x003465, 0x020040, 0x004820,
-       0x025060, 0x40000A, 0x024060, 0x000040,
-       0x454944, 0x000007, 0x004020, 0x003AE5,
-       0x000040, 0x0028E5, 0x000042, 0x48000A,
-       0x004904, 0x386886, 0x002C65, 0x000042,
-       0x40000A, 0x0000D5, 0x454104, 0x000007,
-       0x000655, 0x054504, 0x34F286, 0x0001D5,
-       0x054504, 0x34F086, 0x002B65, 0x000042,
-       0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
-       0x000007, 0x454504, 0x000007, 0x0000CD,
-       0x444944, 0x000007, 0x454504, 0x000007,
-       0x00014D, 0x554944, 0x000007, 0x045144,
-       0x34E986, 0x002C65, 0x000042, 0x48000A,
-       0x4CD104, 0x000007, 0x04C144, 0x34F386,
-       0x000007, 0x160007, 0x002CE5, 0x040042,
-       0x40000A, 0x004020, 0x000040, 0x002965,
-       0x000042, 0x40000A, 0x004104, 0x356086,
-       0x000007, 0x002402, 0x36A206, 0x005C02,
-       0x0025E5, 0x000042, 0x40000A, 0x004274,
-       0x002AE5, 0x000042, 0x40000A, 0x004274,
-       0x500112, 0x0029E5, 0x000042, 0x40000A,
-       0x004234, 0x454104, 0x000007, 0x004020,
-       0x000040, 0x003EE5, 0x000020, 0x000040,
-       0x002DE5, 0x400152, 0x50000A, 0x045144,
-       0x364A86, 0x0000C5, 0x003EE5, 0x004020,
-       0x000040, 0x002BE5, 0x000042, 0x40000A,
-       0x404254, 0x000007, 0x002AE5, 0x004020,
-       0x000040, 0x500132, 0x040134, 0x005674,
-       0x0029E5, 0x020042, 0x42000A, 0x000042,
-       0x50000A, 0x05417C, 0x0028E5, 0x000042,
-       0x48000A, 0x0000C5, 0x4CC144, 0x371086,
-       0x0026E5, 0x0027E5, 0x020042, 0x40004A,
-       0x50000A, 0x00423C, 0x00567C, 0x0028E5,
-       0x004820, 0x000040, 0x281D12, 0x282512,
-       0x001F72, 0x002965, 0x000042, 0x40000A,
-       0x004104, 0x37AA86, 0x0E0007, 0x160007,
-       0x1E0007, 0x003EE5, 0x000042, 0x40000A,
-       0x004104, 0x37E886, 0x002D65, 0x000042,
-       0x28340A, 0x003465, 0x020042, 0x42004A,
-       0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
-       0x54D104, 0x00735C, 0x385186, 0x000007,
-       0x000606, 0x080007, 0x0C0007, 0x080007,
-       0x0A0007, 0x0001E5, 0x020045, 0x004020,
-       0x000060, 0x000365, 0x000040, 0x002E65,
-       0x001A20, 0x0A1A60, 0x000040, 0x003465,
-       0x020042, 0x42004A, 0x004020, 0x4A004A,
-       0x000606, 0x50004A, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000
-};
-
-// --------------------------------------------
-//  DS-1E Controller InstructionRAM Code
-//     1999/06/21
-//     Buf441 slot is Enabled.
-// --------------------------------------------
-// 04/09  creat
-// 04/12  stop nise fix
-// 06/21  WorkingOff timming
-static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
-       0x000007, 0x240007, 0x0C0007, 0x1C0007,
-       0x060007, 0x700002, 0x000020, 0x030040,
-       0x007104, 0x004286, 0x030040, 0x000F0D,
-       0x000810, 0x20043A, 0x000282, 0x00020D,
-       0x000810, 0x20043A, 0x001282, 0x200E82,
-       0x00800D, 0x000810, 0x20043A, 0x001A82,
-       0x03460D, 0x000810, 0x10043A, 0x02EC0D,
-       0x000810, 0x18043A, 0x00010D, 0x020015,
-       0x0000FD, 0x000020, 0x038860, 0x039060,
-       0x038060, 0x038040, 0x038040, 0x038040,
-       0x018040, 0x000A7D, 0x038040, 0x038040,
-       0x018040, 0x200402, 0x000882, 0x08001A,
-       0x000904, 0x017186, 0x000007, 0x260007,
-       0x400007, 0x000007, 0x03258D, 0x000810,
-       0x18043A, 0x260007, 0x284402, 0x00087D,
-       0x018042, 0x00160A, 0x05A206, 0x000007,
-       0x440007, 0x00230D, 0x000810, 0x08043A,
-       0x22FA06, 0x000007, 0x0007FD, 0x018042,
-       0x08000A, 0x000904, 0x02AB86, 0x000195,
-       0x090D04, 0x000007, 0x000820, 0x0000F5,
-       0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
-       0x018040, 0x000A7D, 0x038042, 0x13804A,
-       0x18000A, 0x001820, 0x059060, 0x058860,
-       0x018040, 0x0000FD, 0x018042, 0x70000A,
-       0x000115, 0x071144, 0x033B86, 0x030000,
-       0x007020, 0x036206, 0x018040, 0x00360D,
-       0x000810, 0x08043A, 0x232206, 0x000007,
-       0x02EC0D, 0x000810, 0x18043A, 0x019A06,
-       0x000007, 0x240007, 0x000F8D, 0x000810,
-       0x00163A, 0x002402, 0x005C02, 0x0028FD,
-       0x000020, 0x018040, 0x08000D, 0x000815,
-       0x510984, 0x000007, 0x00004D, 0x000E5D,
-       0x000E02, 0x00430D, 0x000810, 0x08043A,
-       0x2E1206, 0x000007, 0x00008D, 0x000924,
-       0x000F02, 0x00470D, 0x000810, 0x08043A,
-       0x2E1206, 0x000007, 0x480480, 0x001210,
-       0x28043A, 0x00778D, 0x000810, 0x280C3A,
-       0x00068D, 0x000810, 0x28143A, 0x284402,
-       0x03258D, 0x000810, 0x18043A, 0x07FF8D,
-       0x000820, 0x0002FD, 0x018040, 0x260007,
-       0x200007, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x051286, 0x000007, 0x240007,
-       0x02EC0D, 0x000810, 0x18043A, 0x00387D,
-       0x018042, 0x08000A, 0x001015, 0x010984,
-       0x019B86, 0x000007, 0x01B206, 0x000007,
-       0x0008FD, 0x018042, 0x18000A, 0x001904,
-       0x22B886, 0x280007, 0x001810, 0x28043A,
-       0x280C02, 0x00000D, 0x000810, 0x28143A,
-       0x08808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00020D, 0x189904, 0x000007,
-       0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x065A86, 0x000007,
-       0x000100, 0x000A20, 0x00047D, 0x018040,
-       0x018042, 0x20000A, 0x003015, 0x012144,
-       0x036186, 0x000007, 0x002104, 0x036186,
-       0x000007, 0x000F8D, 0x000810, 0x280C3A,
-       0x023944, 0x07C986, 0x000007, 0x001810,
-       0x28043A, 0x08810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x002810, 0x78003A,
-       0x00788D, 0x000810, 0x08043A, 0x2A1206,
-       0x000007, 0x00400D, 0x001015, 0x189904,
-       0x292904, 0x393904, 0x000007, 0x070206,
-       0x000007, 0x0004F5, 0x00007D, 0x000020,
-       0x00008D, 0x010860, 0x018040, 0x00047D,
-       0x038042, 0x21804A, 0x18000A, 0x021944,
-       0x229086, 0x000007, 0x004075, 0x71F104,
-       0x000007, 0x010042, 0x28000A, 0x002904,
-       0x225886, 0x000007, 0x003C0D, 0x30A904,
-       0x000007, 0x00077D, 0x018042, 0x08000A,
-       0x000904, 0x08DA86, 0x00057D, 0x002820,
-       0x03B060, 0x08F206, 0x018040, 0x003020,
-       0x03A860, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x08FA86, 0x000007,
-       0x00057D, 0x018042, 0x28040A, 0x000E8D,
-       0x000810, 0x280C3A, 0x00000D, 0x000810,
-       0x28143A, 0x09000D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x003DFD, 0x000020,
-       0x018040, 0x00107D, 0x009D8D, 0x000810,
-       0x08043A, 0x2A1206, 0x000007, 0x000815,
-       0x08001A, 0x010984, 0x0A5186, 0x00137D,
-       0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x038A60, 0x018040, 0x00107D, 0x018042,
-       0x08000A, 0x000215, 0x010984, 0x3A8186,
-       0x000007, 0x007FBD, 0x383DC4, 0x000007,
-       0x001A7D, 0x001375, 0x018042, 0x09004A,
-       0x10000A, 0x0B8D04, 0x139504, 0x000007,
-       0x000820, 0x019060, 0x001104, 0x225886,
-       0x010040, 0x0017FD, 0x018042, 0x08000A,
-       0x000904, 0x225A86, 0x000007, 0x00197D,
-       0x038042, 0x09804A, 0x10000A, 0x000924,
-       0x001664, 0x0011FD, 0x038042, 0x2B804A,
-       0x19804A, 0x00008D, 0x218944, 0x000007,
-       0x002244, 0x0C1986, 0x000007, 0x001A64,
-       0x002A24, 0x00197D, 0x080102, 0x100122,
-       0x000820, 0x039060, 0x018040, 0x003DFD,
-       0x00008D, 0x000820, 0x018040, 0x001375,
-       0x001A7D, 0x010042, 0x09804A, 0x10000A,
-       0x00021D, 0x0189E4, 0x2992E4, 0x309144,
-       0x000007, 0x00060D, 0x000A15, 0x000C1D,
-       0x001025, 0x00A9E4, 0x012BE4, 0x000464,
-       0x01B3E4, 0x0232E4, 0x000464, 0x000464,
-       0x000464, 0x000464, 0x00040D, 0x08B1C4,
-       0x000007, 0x000820, 0x000BF5, 0x030040,
-       0x00197D, 0x038042, 0x09804A, 0x000A24,
-       0x08000A, 0x080E64, 0x000007, 0x100122,
-       0x000820, 0x031060, 0x010040, 0x0064AC,
-       0x00027D, 0x000020, 0x018040, 0x00107D,
-       0x018042, 0x0011FD, 0x3B804A, 0x09804A,
-       0x20000A, 0x000095, 0x1A1144, 0x00A144,
-       0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
-       0x0018FD, 0x018042, 0x0010FD, 0x09804A,
-       0x28000A, 0x000095, 0x010924, 0x002A64,
-       0x0E4986, 0x000007, 0x002904, 0x0E5A86,
-       0x000007, 0x0E6206, 0x080002, 0x00008D,
-       0x00387D, 0x000820, 0x018040, 0x00127D,
-       0x018042, 0x10000A, 0x003904, 0x0F0986,
-       0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
-       0x000025, 0x0FB206, 0x00002D, 0x000015,
-       0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
-       0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
-       0x400025, 0x00008D, 0x110944, 0x000007,
-       0x00018D, 0x109504, 0x000007, 0x009164,
-       0x000424, 0x000424, 0x000424, 0x100102,
-       0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
-       0x00018D, 0x00042D, 0x00008D, 0x109504,
-       0x000007, 0x00020D, 0x109184, 0x000007,
-       0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
-       0x018040, 0x003BFD, 0x001020, 0x03A860,
-       0x000815, 0x313184, 0x212184, 0x000007,
-       0x03B060, 0x03A060, 0x018040, 0x0022FD,
-       0x000095, 0x010924, 0x000424, 0x000424,
-       0x001264, 0x100102, 0x000820, 0x039060,
-       0x018040, 0x001924, 0x010F0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x000424, 0x000424,
-       0x00117D, 0x018042, 0x08000A, 0x000A24,
-       0x280502, 0x280C02, 0x09800D, 0x000820,
-       0x0002FD, 0x018040, 0x200007, 0x0022FD,
-       0x018042, 0x08000A, 0x000095, 0x280DC4,
-       0x011924, 0x00197D, 0x018042, 0x0011FD,
-       0x09804A, 0x10000A, 0x0000B5, 0x113144,
-       0x0A8D04, 0x000007, 0x080A44, 0x129504,
-       0x000007, 0x0023FD, 0x001020, 0x038040,
-       0x101244, 0x000007, 0x000820, 0x039060,
-       0x018040, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x123286, 0x000007, 0x003BFD,
-       0x000100, 0x000A10, 0x0B807A, 0x13804A,
-       0x090984, 0x000007, 0x000095, 0x013D04,
-       0x12B886, 0x10000A, 0x100002, 0x090984,
-       0x000007, 0x038042, 0x11804A, 0x090D04,
-       0x000007, 0x10000A, 0x090D84, 0x000007,
-       0x00257D, 0x000820, 0x018040, 0x00010D,
-       0x000810, 0x28143A, 0x00127D, 0x018042,
-       0x20000A, 0x00197D, 0x018042, 0x00117D,
-       0x31804A, 0x10000A, 0x003124, 0x013B8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x300102,
-       0x003124, 0x000424, 0x000424, 0x001224,
-       0x280502, 0x001A4C, 0x143986, 0x700002,
-       0x00002D, 0x030000, 0x00387D, 0x018042,
-       0x10000A, 0x146206, 0x002124, 0x0000AD,
-       0x100002, 0x00010D, 0x000924, 0x006B24,
-       0x014A0D, 0x00397D, 0x000820, 0x058040,
-       0x038042, 0x09844A, 0x000606, 0x08040A,
-       0x003264, 0x00008D, 0x000A24, 0x001020,
-       0x00227D, 0x018040, 0x014F8D, 0x000810,
-       0x08043A, 0x2B5A06, 0x000007, 0x002820,
-       0x00207D, 0x018040, 0x00117D, 0x038042,
-       0x13804A, 0x33800A, 0x00387D, 0x018042,
-       0x08000A, 0x000904, 0x177286, 0x000007,
-       0x00008D, 0x030964, 0x015B0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x380102, 0x000424,
-       0x000424, 0x001224, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x15DA86, 0x000007,
-       0x280502, 0x001A4C, 0x177186, 0x000007,
-       0x032164, 0x00632C, 0x003DFD, 0x018042,
-       0x08000A, 0x000095, 0x090904, 0x000007,
-       0x000820, 0x001A4C, 0x169986, 0x018040,
-       0x030000, 0x16B206, 0x002124, 0x00010D,
-       0x000924, 0x006B24, 0x016F0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x003A64, 0x000095,
-       0x001224, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x171286, 0x000007, 0x01760D,
-       0x000810, 0x08043A, 0x2B5A06, 0x000007,
-       0x160A06, 0x000007, 0x007020, 0x08010A,
-       0x10012A, 0x0020FD, 0x038860, 0x039060,
-       0x018040, 0x00227D, 0x018042, 0x003DFD,
-       0x08000A, 0x31844A, 0x000904, 0x181086,
-       0x18008B, 0x00008D, 0x189904, 0x00312C,
-       0x18E206, 0x000007, 0x00324C, 0x186B86,
-       0x000007, 0x001904, 0x186886, 0x000007,
-       0x000095, 0x199144, 0x00222C, 0x003124,
-       0x00636C, 0x000E3D, 0x001375, 0x000BFD,
-       0x010042, 0x09804A, 0x10000A, 0x038AEC,
-       0x0393EC, 0x00224C, 0x18E186, 0x000007,
-       0x00008D, 0x189904, 0x00226C, 0x00322C,
-       0x30050A, 0x301DAB, 0x002083, 0x0018FD,
-       0x018042, 0x08000A, 0x018924, 0x300502,
-       0x001083, 0x001875, 0x010042, 0x10000A,
-       0x00008D, 0x010924, 0x001375, 0x330542,
-       0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
-       0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
-       0x006083, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x19B286, 0x000007, 0x001E2D,
-       0x0005FD, 0x018042, 0x08000A, 0x028924,
-       0x280502, 0x00060D, 0x000810, 0x280C3A,
-       0x00008D, 0x000810, 0x28143A, 0x0A808D,
-       0x000820, 0x0002F5, 0x010040, 0x220007,
-       0x001275, 0x030042, 0x21004A, 0x00008D,
-       0x1A0944, 0x000007, 0x01AB8D, 0x000810,
-       0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
-       0x030042, 0x0D004A, 0x10000A, 0x089144,
-       0x000007, 0x000820, 0x010040, 0x0025F5,
-       0x0A3144, 0x000007, 0x000820, 0x032860,
-       0x030040, 0x00217D, 0x038042, 0x0B804A,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x00008D, 0x000124, 0x00012C, 0x000E64,
-       0x001A64, 0x00636C, 0x08010A, 0x10012A,
-       0x000820, 0x031060, 0x030040, 0x0020FD,
-       0x018042, 0x08000A, 0x00227D, 0x018042,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x00197D, 0x018042, 0x08000A, 0x0022FD,
-       0x038042, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x090D04, 0x000007, 0x000820,
-       0x030040, 0x038042, 0x0B804A, 0x10000A,
-       0x000820, 0x031060, 0x030040, 0x038042,
-       0x13804A, 0x19804A, 0x110D04, 0x198D04,
-       0x000007, 0x08000A, 0x001020, 0x031860,
-       0x030860, 0x030040, 0x00008D, 0x0B0944,
-       0x000007, 0x000820, 0x010040, 0x0005F5,
-       0x030042, 0x08000A, 0x000820, 0x010040,
-       0x0000F5, 0x010042, 0x08000A, 0x000904,
-       0x1D9886, 0x001E75, 0x030042, 0x01044A,
-       0x000C0A, 0x1DAA06, 0x000007, 0x000402,
-       0x000C02, 0x00177D, 0x001AF5, 0x018042,
-       0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
-       0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
-       0x00043D, 0x0013F5, 0x001AFD, 0x030042,
-       0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-       0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-       0x005502, 0x005D0A, 0x030042, 0x0B004A,
-       0x1B804A, 0x13804A, 0x20000A, 0x089144,
-       0x19A144, 0x0389E4, 0x0399EC, 0x006502,
-       0x006D0A, 0x030042, 0x0B004A, 0x19004A,
-       0x2B804A, 0x13804A, 0x21804A, 0x30000A,
-       0x089144, 0x19A144, 0x2AB144, 0x0389E4,
-       0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
-       0x000702, 0x00107D, 0x000415, 0x018042,
-       0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
-       0x0019FD, 0x010042, 0x09804A, 0x10000A,
-       0x000934, 0x001674, 0x0029F5, 0x010042,
-       0x10000A, 0x00917C, 0x002075, 0x010042,
-       0x08000A, 0x000904, 0x200A86, 0x0026F5,
-       0x0027F5, 0x030042, 0x09004A, 0x10000A,
-       0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
-       0x010042, 0x51804A, 0x48000A, 0x160007,
-       0x001075, 0x010042, 0x282C0A, 0x281D12,
-       0x282512, 0x001F32, 0x1E0007, 0x0E0007,
-       0x001975, 0x010042, 0x002DF5, 0x0D004A,
-       0x10000A, 0x009144, 0x20EA86, 0x010042,
-       0x28340A, 0x000E5D, 0x00008D, 0x000375,
-       0x000820, 0x010040, 0x05D2F4, 0x54D104,
-       0x00735C, 0x218B86, 0x000007, 0x0C0007,
-       0x080007, 0x0A0007, 0x02178D, 0x000810,
-       0x08043A, 0x34B206, 0x000007, 0x219206,
-       0x000007, 0x080007, 0x002275, 0x010042,
-       0x20000A, 0x002104, 0x225886, 0x001E2D,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x21CA86, 0x000007, 0x002010, 0x30043A,
-       0x00057D, 0x0180C3, 0x08000A, 0x028924,
-       0x280502, 0x280C02, 0x0A810D, 0x000820,
-       0x0002F5, 0x010040, 0x220007, 0x0004FD,
-       0x018042, 0x70000A, 0x030000, 0x007020,
-       0x07FA06, 0x018040, 0x022B8D, 0x000810,
-       0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x22C286,
-       0x000007, 0x020206, 0x000007, 0x000875,
-       0x0009FD, 0x00010D, 0x234206, 0x000295,
-       0x000B75, 0x00097D, 0x00000D, 0x000515,
-       0x010042, 0x18000A, 0x001904, 0x2A0086,
-       0x0006F5, 0x001020, 0x010040, 0x0004F5,
-       0x000820, 0x010040, 0x000775, 0x010042,
-       0x09804A, 0x10000A, 0x001124, 0x000904,
-       0x23F286, 0x000815, 0x080102, 0x101204,
-       0x241206, 0x000575, 0x081204, 0x000007,
-       0x100102, 0x000575, 0x000425, 0x021124,
-       0x100102, 0x000820, 0x031060, 0x010040,
-       0x001924, 0x2A0086, 0x00008D, 0x000464,
-       0x009D04, 0x291086, 0x180102, 0x000575,
-       0x010042, 0x28040A, 0x00018D, 0x000924,
-       0x280D02, 0x00000D, 0x000924, 0x281502,
-       0x10000D, 0x000820, 0x0002F5, 0x010040,
-       0x200007, 0x001175, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x24FA86, 0x000007,
-       0x000100, 0x080B20, 0x130B60, 0x1B0B60,
-       0x030A60, 0x010040, 0x050042, 0x3D004A,
-       0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
-       0x010042, 0x28140A, 0x0004F5, 0x010042,
-       0x08000A, 0x000315, 0x010D04, 0x260286,
-       0x004015, 0x000095, 0x010D04, 0x25F086,
-       0x100022, 0x10002A, 0x261A06, 0x000007,
-       0x333104, 0x2AA904, 0x000007, 0x032124,
-       0x280502, 0x284402, 0x001124, 0x400102,
-       0x000424, 0x000424, 0x003224, 0x00292C,
-       0x00636C, 0x277386, 0x000007, 0x02B164,
-       0x000464, 0x000464, 0x00008D, 0x000A64,
-       0x280D02, 0x10008D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x00008D, 0x38B904,
-       0x000007, 0x03296C, 0x30010A, 0x0002F5,
-       0x010042, 0x08000A, 0x000904, 0x270286,
-       0x000007, 0x00212C, 0x28050A, 0x00316C,
-       0x00046C, 0x00046C, 0x28450A, 0x001124,
-       0x006B64, 0x100102, 0x00008D, 0x01096C,
-       0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x004124, 0x000424,
-       0x000424, 0x003224, 0x300102, 0x032944,
-       0x27FA86, 0x000007, 0x300002, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x284086, 0x003124, 0x000464, 0x300102,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x284A86, 0x000007, 0x284402, 0x003124,
-       0x300502, 0x003924, 0x300583, 0x000883,
-       0x0005F5, 0x010042, 0x28040A, 0x00008D,
-       0x008124, 0x280D02, 0x00008D, 0x008124,
-       0x281502, 0x10018D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x001025, 0x000575,
-       0x030042, 0x09004A, 0x10000A, 0x0A0904,
-       0x121104, 0x000007, 0x001020, 0x050860,
-       0x050040, 0x0006FD, 0x018042, 0x09004A,
-       0x10000A, 0x0000A5, 0x0A0904, 0x121104,
-       0x000007, 0x000820, 0x019060, 0x010040,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x29CA86, 0x000007, 0x244206, 0x000007,
-       0x000606, 0x000007, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x2A1A86, 0x000007,
-       0x000100, 0x080B20, 0x138B60, 0x1B8B60,
-       0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
-       0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
-       0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
-       0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
-       0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
-       0x038A60, 0x000606, 0x018040, 0x00008D,
-       0x000A64, 0x280D02, 0x000A24, 0x00027D,
-       0x018042, 0x10000A, 0x001224, 0x0003FD,
-       0x018042, 0x08000A, 0x000904, 0x2C0A86,
-       0x000007, 0x00018D, 0x000A24, 0x000464,
-       0x000464, 0x080102, 0x000924, 0x000424,
-       0x000424, 0x100102, 0x02000D, 0x009144,
-       0x2C6186, 0x000007, 0x0001FD, 0x018042,
-       0x08000A, 0x000A44, 0x2C4386, 0x018042,
-       0x0A000D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00027D, 0x001020, 0x000606,
-       0x018040, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x2CB286, 0x000007, 0x00037D,
-       0x018042, 0x08000A, 0x000904, 0x2CE286,
-       0x000007, 0x000075, 0x002E7D, 0x010042,
-       0x0B804A, 0x000020, 0x000904, 0x000686,
-       0x010040, 0x31844A, 0x30048B, 0x000883,
-       0x00008D, 0x000810, 0x28143A, 0x00008D,
-       0x000810, 0x280C3A, 0x000675, 0x010042,
-       0x08000A, 0x003815, 0x010924, 0x280502,
-       0x0B000D, 0x000820, 0x0002F5, 0x010040,
-       0x000606, 0x220007, 0x000464, 0x000464,
-       0x000606, 0x000007, 0x000134, 0x007F8D,
-       0x00093C, 0x281D12, 0x282512, 0x001F32,
-       0x0E0007, 0x00010D, 0x00037D, 0x000820,
-       0x018040, 0x05D2F4, 0x000007, 0x080007,
-       0x00037D, 0x018042, 0x08000A, 0x000904,
-       0x2E8A86, 0x000007, 0x000606, 0x000007,
-       0x000007, 0x000012, 0x100007, 0x320007,
-       0x600007, 0x460007, 0x100080, 0x48001A,
-       0x004904, 0x2EF186, 0x000007, 0x001210,
-       0x58003A, 0x000145, 0x5C5D04, 0x000007,
-       0x000080, 0x48001A, 0x004904, 0x2F4186,
-       0x000007, 0x001210, 0x50003A, 0x005904,
-       0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
-       0x7FFF7D, 0x07D524, 0x004224, 0x500102,
-       0x200502, 0x000082, 0x40001A, 0x004104,
-       0x2FC986, 0x000007, 0x003865, 0x40001A,
-       0x004020, 0x00104D, 0x04C184, 0x31AB86,
-       0x000040, 0x040007, 0x000165, 0x000145,
-       0x004020, 0x000040, 0x000765, 0x080080,
-       0x40001A, 0x004104, 0x305986, 0x000007,
-       0x001210, 0x40003A, 0x004104, 0x30B286,
-       0x00004D, 0x0000CD, 0x004810, 0x20043A,
-       0x000882, 0x40001A, 0x004104, 0x30C186,
-       0x000007, 0x004820, 0x005904, 0x319886,
-       0x000040, 0x0007E5, 0x200480, 0x2816A0,
-       0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
-       0x000040, 0x000032, 0x400075, 0x00007D,
-       0x07D574, 0x200512, 0x000082, 0x40001A,
-       0x004104, 0x317186, 0x000007, 0x038A06,
-       0x640007, 0x0000E5, 0x000020, 0x000040,
-       0x000A65, 0x000020, 0x020040, 0x020040,
-       0x000040, 0x000165, 0x000042, 0x70000A,
-       0x007104, 0x323286, 0x000007, 0x060007,
-       0x019A06, 0x640007, 0x050000, 0x007020,
-       0x000040, 0x038A06, 0x640007, 0x000007,
-       0x00306D, 0x028860, 0x029060, 0x08000A,
-       0x028860, 0x008040, 0x100012, 0x00100D,
-       0x009184, 0x32D186, 0x000E0D, 0x009184,
-       0x33E186, 0x000007, 0x300007, 0x001020,
-       0x003B6D, 0x008040, 0x000080, 0x08001A,
-       0x000904, 0x32F186, 0x000007, 0x001220,
-       0x000DED, 0x008040, 0x008042, 0x10000A,
-       0x40000D, 0x109544, 0x000007, 0x001020,
-       0x000DED, 0x008040, 0x008042, 0x20040A,
-       0x000082, 0x08001A, 0x000904, 0x338186,
-       0x000007, 0x003B6D, 0x008042, 0x08000A,
-       0x000E15, 0x010984, 0x342B86, 0x600007,
-       0x08001A, 0x000C15, 0x010984, 0x341386,
-       0x000020, 0x1A0007, 0x0002ED, 0x008040,
-       0x620007, 0x00306D, 0x028042, 0x0A804A,
-       0x000820, 0x0A804A, 0x000606, 0x10804A,
-       0x000007, 0x282512, 0x001F32, 0x05D2F4,
-       0x54D104, 0x00735C, 0x000786, 0x000007,
-       0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
-       0x020040, 0x004820, 0x025060, 0x40000A,
-       0x024060, 0x000040, 0x454944, 0x000007,
-       0x004020, 0x003AE5, 0x000040, 0x0028E5,
-       0x000042, 0x48000A, 0x004904, 0x39F886,
-       0x002C65, 0x000042, 0x40000A, 0x0000D5,
-       0x454104, 0x000007, 0x000655, 0x054504,
-       0x368286, 0x0001D5, 0x054504, 0x368086,
-       0x002B65, 0x000042, 0x003AE5, 0x50004A,
-       0x40000A, 0x45C3D4, 0x000007, 0x454504,
-       0x000007, 0x0000CD, 0x444944, 0x000007,
-       0x454504, 0x000007, 0x00014D, 0x554944,
-       0x000007, 0x045144, 0x367986, 0x002C65,
-       0x000042, 0x48000A, 0x4CD104, 0x000007,
-       0x04C144, 0x368386, 0x000007, 0x160007,
-       0x002CE5, 0x040042, 0x40000A, 0x004020,
-       0x000040, 0x002965, 0x000042, 0x40000A,
-       0x004104, 0x36F086, 0x000007, 0x002402,
-       0x383206, 0x005C02, 0x0025E5, 0x000042,
-       0x40000A, 0x004274, 0x002AE5, 0x000042,
-       0x40000A, 0x004274, 0x500112, 0x0029E5,
-       0x000042, 0x40000A, 0x004234, 0x454104,
-       0x000007, 0x004020, 0x000040, 0x003EE5,
-       0x000020, 0x000040, 0x002DE5, 0x400152,
-       0x50000A, 0x045144, 0x37DA86, 0x0000C5,
-       0x003EE5, 0x004020, 0x000040, 0x002BE5,
-       0x000042, 0x40000A, 0x404254, 0x000007,
-       0x002AE5, 0x004020, 0x000040, 0x500132,
-       0x040134, 0x005674, 0x0029E5, 0x020042,
-       0x42000A, 0x000042, 0x50000A, 0x05417C,
-       0x0028E5, 0x000042, 0x48000A, 0x0000C5,
-       0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
-       0x020042, 0x40004A, 0x50000A, 0x00423C,
-       0x00567C, 0x0028E5, 0x004820, 0x000040,
-       0x281D12, 0x282512, 0x001F72, 0x002965,
-       0x000042, 0x40000A, 0x004104, 0x393A86,
-       0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
-       0x000042, 0x40000A, 0x004104, 0x397886,
-       0x002D65, 0x000042, 0x28340A, 0x003465,
-       0x020042, 0x42004A, 0x004020, 0x4A004A,
-       0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
-       0x39E186, 0x000007, 0x000606, 0x080007,
-       0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
-       0x020045, 0x004020, 0x000060, 0x000365,
-       0x000040, 0x002E65, 0x001A20, 0x0A1A60,
-       0x000040, 0x003465, 0x020042, 0x42004A,
-       0x004020, 0x4A004A, 0x000606, 0x50004A,
-       0x0017FD, 0x018042, 0x08000A, 0x000904,
-       0x225A86, 0x000007, 0x00107D, 0x018042,
-       0x0011FD, 0x33804A, 0x19804A, 0x20000A,
-       0x000095, 0x2A1144, 0x01A144, 0x3B9086,
-       0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
-       0x018042, 0x0010FD, 0x09804A, 0x38000A,
-       0x000095, 0x010924, 0x003A64, 0x3B8186,
-       0x000007, 0x003904, 0x3B9286, 0x000007,
-       0x3B9A06, 0x00000D, 0x00008D, 0x000820,
-       0x00387D, 0x018040, 0x700002, 0x00117D,
-       0x018042, 0x00197D, 0x29804A, 0x30000A,
-       0x380002, 0x003124, 0x000424, 0x000424,
-       0x002A24, 0x280502, 0x00068D, 0x000810,
-       0x28143A, 0x00750D, 0x00B124, 0x002264,
-       0x3D0386, 0x284402, 0x000810, 0x280C3A,
-       0x0B800D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00758D, 0x00B124, 0x100102,
-       0x012144, 0x3E4986, 0x001810, 0x10003A,
-       0x00387D, 0x018042, 0x08000A, 0x000904,
-       0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
-       0x00008D, 0x023164, 0x000A64, 0x280D02,
-       0x0B808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00387D, 0x018042, 0x08000A,
-       0x000904, 0x3E3286, 0x030000, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x3D8286,
-       0x000007, 0x002810, 0x28043A, 0x00750D,
-       0x030924, 0x002264, 0x280D02, 0x02316C,
-       0x28450A, 0x0B810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x00008D, 0x000A24,
-       0x3E4A06, 0x100102, 0x001810, 0x10003A,
-       0x0000BD, 0x003810, 0x30043A, 0x00187D,
-       0x018042, 0x0018FD, 0x09804A, 0x20000A,
-       0x0000AD, 0x028924, 0x07212C, 0x001010,
-       0x300583, 0x300D8B, 0x3014BB, 0x301C83,
-       0x002083, 0x00137D, 0x038042, 0x33844A,
-       0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
-       0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
-       0x001E0D, 0x0005FD, 0x018042, 0x20000A,
-       0x020924, 0x00068D, 0x00A96C, 0x00009D,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x3F6A86, 0x000007, 0x280502, 0x280D0A,
-       0x284402, 0x001810, 0x28143A, 0x0C008D,
-       0x000820, 0x0002FD, 0x018040, 0x220007,
-       0x003904, 0x225886, 0x001E0D, 0x00057D,
-       0x018042, 0x20000A, 0x020924, 0x0000A5,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x402A86, 0x000007, 0x280502, 0x280C02,
-       0x002010, 0x28143A, 0x0C010D, 0x000820,
-       0x0002FD, 0x018040, 0x225A06, 0x220007,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000
-};
-
-#endif //_HWMCODE_
diff --git a/sound/oss/yss225.c b/sound/oss/yss225.c
deleted file mode 100644 (file)
index e700400..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-#include <linux/init.h>
-
-unsigned char page_zero[] __initdata = {
-0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
-0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00,
-0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19,
-0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01,
-0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00,
-0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02,
-0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,
-0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00,
-0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02,
-0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40,
-0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02,
-0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00,
-0x1d, 0x02, 0xdf
-};    
-
-unsigned char page_one[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
-0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00,
-0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
-0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00,
-0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7,
-0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00,
-0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03,
-0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00,
-0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02,
-0x60, 0x00, 0x1b
-};
-
-unsigned char page_two[] __initdata = {
-0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4,
-0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07,
-0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46,
-0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46,
-0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07,
-0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05,
-0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05,
-0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44
-};
-
-unsigned char page_three[] __initdata = {
-0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
-0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40,
-0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00,
-0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40
-};
-
-unsigned char page_four[] __initdata = {
-0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
-0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60,
-0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00,
-0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22,
-0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01
-};
-
-unsigned char page_six[] __initdata = {
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
-0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e,
-0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00,
-0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24,
-0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00,
-0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00,
-0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a,
-0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d,
-0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50,
-0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00,
-0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17,
-0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66,
-0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c,
-0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00,
-0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c,
-0x80, 0x00, 0x7e, 0x80, 0x80
-};
-
-unsigned char page_seven[] __initdata = {
-0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f,
-0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff,
-0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f,
-0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38,
-0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06,
-0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b,
-0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06,
-0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55,
-0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14,
-0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93,
-0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00
-};
-
-unsigned char page_zero_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_one_v2[] __initdata = {
-0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_two_v2[] __initdata = {
-0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_three_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_four_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_seven_v2[] __initdata = {
-0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-unsigned char mod_v2[] __initdata = {
-0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02,
-0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05,
-0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0,
-0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20,
-0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3,
-0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff,
-0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16,
-0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff,
-0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31,
-0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00,
-0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44,
-0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00,
-0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
-0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00,
-0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72,
-0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0,
-0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85,
-0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00,
-0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0,
-0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00,
-0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
-0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00,
-0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6,
-0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00,
-0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02,
-0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03,
-0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01,
-0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01
-};
-unsigned char coefficients[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03,
-0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49,
-0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01,
-0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00,
-0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47,
-0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07,
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00,
-0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01,
-0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43,
-0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07,
-0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02,
-0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44,
-0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07,
-0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40,
-0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a,
-0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56,
-0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07,
-0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda,
-0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05,
-0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79,
-0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07,
-0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52,
-0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03,
-0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a,
-0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06,
-0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3,
-0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20,
-0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c,
-0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06,
-0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48,
-0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02,
-0xba
-};
-unsigned char coefficients2[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f,
-0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d,
-0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07,
-0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00,
-0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00
-};
-unsigned char coefficients3[] __initdata = { 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00,
-0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc,
-0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01,
-0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99,
-0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02,
-0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f,
-0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03,
-0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c,
-0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03,
-0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51,
-0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04,
-0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e,
-0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05,
-0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14,
-0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06,
-0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1,
-0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07,
-0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7,
-0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08,
-0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3,
-0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09,
-0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99,
-0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a,
-0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66,
-0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a,
-0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c,
-0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b,
-0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28,
-0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c,
-0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e,
-0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d,
-0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb,
-0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e,
-0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1,
-0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f,
-0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae,
-0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff
-};
-
diff --git a/sound/oss/yss225.h b/sound/oss/yss225.h
deleted file mode 100644 (file)
index 56d8b6b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __yss255_h__
-#define __yss255_h__
-
-extern unsigned char page_zero[256];
-extern unsigned char page_one[256];
-extern unsigned char page_two[128];
-extern unsigned char page_three[128];
-extern unsigned char page_four[128];
-extern unsigned char page_six[192];
-extern unsigned char page_seven[256];
-extern unsigned char page_zero_v2[96];
-extern unsigned char page_one_v2[96];
-extern unsigned char page_two_v2[48];
-extern unsigned char page_three_v2[48];
-extern unsigned char page_four_v2[48];
-extern unsigned char page_seven_v2[96];
-extern unsigned char mod_v2[304];
-extern unsigned char coefficients[364];
-extern unsigned char coefficients2[56];
-extern unsigned char coefficients3[404];
-
-
-#endif /* __ys225_h__ */
-
index 0b0a016ca6d691563eac593634bc9dbdb3a39a7f..5322c50c9617c2f8aa0850b60e873a5caef26c2d 100644 (file)
@@ -365,25 +365,6 @@ int register_sound_dsp(const struct file_operations *fops, int dev)
 
 EXPORT_SYMBOL(register_sound_dsp);
 
-/**
- *     register_sound_synth - register a synth device
- *     @fops: File operations for the driver
- *     @dev: Unit number to allocate
- *
- *     Allocate a synth device. Unit is the number of the synth device requested.
- *     Pass -1 to request the next free synth unit. On success the allocated
- *     number is returned, on failure a negative error code is returned.
- */
-
-
-int register_sound_synth(const struct file_operations *fops, int dev)
-{
-       return sound_insert_unit(&chains[9], fops, dev, 9, 137,
-                                "synth", S_IRUSR | S_IWUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_synth);
-
 /**
  *     unregister_sound_special - unregister a special sound device
  *     @unit: unit number to allocate
@@ -449,21 +430,6 @@ void unregister_sound_dsp(int unit)
 
 EXPORT_SYMBOL(unregister_sound_dsp);
 
-/**
- *     unregister_sound_synth - unregister a synth device
- *     @unit: unit number to allocate
- *
- *     Release a sound device that was allocated with register_sound_synth().
- *     The unit passed is the return value from the register function.
- */
-
-void unregister_sound_synth(int unit)
-{
-       return sound_remove_unit(&chains[9], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_synth);
-
 /*
  *     Now our file operations
  */